diff --git a/.gitignore b/.gitignore index 734b3388fa3644d7d54d94e65e49f94b24ea08f3..14a9344aef78716a4e54d10e81ea5c94a85d1c27 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ map_images/ web/src/main/webapp/svnversion.txt *.war /target/ -service/minerva-big/ \ No newline at end of file +service/minerva-big/ +npm-debug.log \ No newline at end of file diff --git a/README.md b/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e5e5c708c7405edcf459c632dcc8ed840d8f13f2 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,355 @@ +# Rest API (version 11) + +## Introduction + +Rest API is located in /api/ path of the deployed application. For instance, Rest API of pdmap project that can be browsed using http://pdmap.uni.lu/minerva/ will be located here: http://pdmap.uni.lu/minerva/api/ + +Rest API tries to follow [API Design Guide](https://cloud.google.com/apis/design/) by Google. + +All API calls (except login) must include MINERVA_AUTH_TOKEN obtained due login process. + +## Quickstart guide + +To use API first we need to login: +`curl -X POST -c - --data "login=anonymous&password=" http://pg-sandbox.uni.lu/minerva/api/doLogin` + +``` + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed +100 55 0 55 0 0 1774 0 --:--:-- --:--:-- --:--:-- 1774{"info":"Login successful. TOKEN returned as a cookie"}# Netscape HTTP Cookie File +# https://curl.haxx.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +localhost FALSE / FALSE 1496934071 MINERVA_AUTH_TOKEN xxxxxxxx +``` +The response creates an authentication token and puts it into a cookie `MINERVA_AUTH_TOKEN=xxxxxxxx`. When using console curl command this cookie must be attached to every query that follows. +When we have authentication token we can access information about december release of PD map project: +` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/ +` + +## Specification + +### Authentication +* Login: + * URL: `/doLogin` + * Method: POST + * Parameters: + * `login` - user login, 'anonymous' can be used for accessing api with guest account access level + * `password` - user passwod, for guest account this field is optional + * Output. If login operation is successfull then `MINERVA_AUTH_TOKEN` cookie will be created with authentication token. If credentails are invalid response with `403` status code will be returned. Token will be valid for the next 120 minutes. + * Example: +``` +curl -X POST -c - --data "login=anonymous&password=" http://pg-sandbox.uni.lu/minerva/api/doLogin +``` + +* Login: + * URL: `/doLogout` + * Method: POST + * Example: +``` +curl -X POST -c - http://pg-sandbox.uni.lu/minerva/api/doLogout +``` + + +### Configuration +* URL: `/configuration/` +* Method: GET +* Parameters: *NONE* +* Output: List of all minerva configuration details. +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/configuration/ +``` + +### Genomics +* URL: `/genomics/taxonomies/{organismId}/genomeTypes/{type}/versions/{version}/` +* Method: GET +* Parameters: + * organismId - identifier of the organism in taxonomy db + * type - type of genome (database from which reference genome should be used), for now only UCSC is supported + * version - version of the reference genome +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/genomics/taxonomies/9606/genomeTypes/UCSC/versions/hg19/ +``` + +### Projects + +* Project data: + * URL: `/projects/{projectId}/` + * Method: GET + * Parameters: + * projectId - identifier of the project + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/ +``` + +* Source file: + * URL: `/projects/{projectId}:downloadSource` + * Method: GET + * Parameters: + * projectId - identifier of the project + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_jun16:downloadSource --output some.file +``` + +#### (sub)Maps +* Download map as a model file (ie. in CellDesigner format) + * URL: `/projects/{projectId}/models/{modelId}:downloadModel` + * Method: GET + * Parameters: TODO, + * See also `/configuration/` query to get list of possible formats + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" "http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/15305:downloadModel?handlerClass=lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser" --output some.file +``` + +* Download map as an image + * URL: `/projects/{projectId}/models/{modelId}:downloadImage` + * Method: GET + * Parameters: TODO, + * See also `/configuration/` query to get list of possible formats + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" "http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/15305:downloadImage?handlerClass=lcsb.mapviewer.converter.graphics.PngImageGenerator" --output some.file +``` + +* Elements: + * URL: `/projects/{projectId}/models/{modelId}/bioEntities/elements/` + * Method: GET + * Parameters: + * `columns` - set of columns. Possible values are: id, modelId, name, type, description, symbol, complexId, compartmentId, fullName, abbreviation, formula, name, synonyms, formerSymbols, references, bounds, hierarchyVisibilityLevel, + * `ids` - set of database ids + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/*/bioEntities/elements/?columns=id,name,type +``` + +* Reactions: + * URL: `/projects/{projectId}/models/{modelId}/bioEntities/reactions/` + * Method: GET + * Parameters: + * `columns` - set of columns. Possible values are: + * `ids` - set of database ids + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/*/bioEntities/reactions/?columns=id,name,type +``` + +* Search: + * URL: `/projects/{projectId}/models/{modelId}/bioEntities:search` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/*/bioEntities:search?query=SNCA +``` + +* Suggested search queries: + * URL: `/projects/{projectId}/models/{modelId}/bioEntities/suggestedQueryList` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/*/bioEntities/suggestedQueryList +``` + + +#### Chemicals +* URL: `/projects/{projectId}/chemicals:search` +* Method: GET +* Parameters: TODO +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" "http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/chemicals:search?query=rotenone" +``` + +#### Comments +* List comments + * URL: `/projects/{projectId}/comments/models/{modelId}/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" "http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/*/" +``` + +* Reaction comments + * URL: `/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/15305/bioEntities/reactions/187811/ +``` + +* Element comments + * URL: `/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/15305/bioEntities/elements/431868/ +``` + +* Point comments + * URL: `/projects/{projectId}/comments/models/{modelId}/points/{coordinates}` + * Method: GET + * Parameters: TODO + * Example: TODO + +* Create element comment + * URL: `/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}` + * Method: POST + * Parameters: TODO + * Example: +``` +curl -X POST --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" --data "name=testComment&email=a@a.pl&content=someCont&coordinates=1,2" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/15305/bioEntities/elements/431868/ +``` + +* Create reaction comment + * URL: `/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}` + * Method: POST + * Parameters: TODO + * Example: +``` +curl -X POST --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" --data "name=testComment&email=a@a.pl&content=someCont&coordinates=1,2" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/15305/bioEntities/reactions/187811 +``` + + +* Create coordinates comment + * URL: `/projects/{projectId}/comments/models/{modelId}/points/{coordinates}` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X POST --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" --data "name=testComment&email=a@a.pl&content=someCont" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/comments/models/15305/points/1.00,2.00 +``` + +#### Drugs +* URL: `/projects/{projectId}/drugs:search` +* Method: GET +* Parameters: TODO +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/drugs:search?query=aspirin +``` + +#### MiRNAs + +* URL: `/projects/{projectId}/miRnas:search` +* Method: GET +* Parameters: TODO +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/miRnas:search?query=hsa-miR-125a-3p +``` + + +#### Publications + +* URL: `/projects/{projectId}/models/{modelId}/publications/` +* Method: GET +* Parameters: TODO +* Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/models/*/publications/ +``` + +#### Data overlays +* List user data overlays + * URL: `/projects/{projectId}/overlays/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/ +``` + +* Data overlay + * URL: `/projects/{projectId}/overlays/{overlayId}/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/ +``` + +* bioEntities (Elements and reactions) + * URL: `/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/models/*/bioEntities/ +``` + +* Reaction + * URL: `/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/reactions/{reactionId}/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/models/15305/bioEntities/reactions/187811/ +``` + +* Element + * URL: `/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/elements/{elementId}/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/models/15305/bioEntities/elements/431433/ +``` + +* Update overlay + * URL: `/projects/{projectId}/overlays/{overlayId}/` + * Method: PATCH + * Parameters: TODO + * Example: +``` +curl -X PATCH --data "{\"overlay\":{\"name\":\"test\", \"description\":\"test2\"}}" --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/ +``` + + +* Remove overlay + * URL: `/projects/{projectId}/overlays/{overlayId}/` + * Method: DELETE + * Parameters: TODO + * Example: +``` +curl -X DELETE --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203/ +``` + +* Download source + * URL: `/projects/{projectId}/overlays/{overlayId}:downloadSource` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/3203:downloadSource +``` + +* Add overlay + * URL: `/projects/{projectId}/overlays/` + * Method: POST + * Parameters: TODO + * Example: +``` +curl -X POST --data "content=name%09color%0ACAPN1%09%2300FF00%0APARK7%09%23AC0000&description=test%20desc&filename=test.txt&name=test%20nam" --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/projects/pdmap_dec15/overlays/ +``` + + +### Users +* User data + * URL: `/users/{login}/` + * Method: GET + * Parameters: TODO + * Example: +``` +curl -X GET --cookie "MINERVA_AUTH_TOKEN=xxxxxxxx" http://pg-sandbox.uni.lu/minerva/api/users/testAdmin +``` + \ No newline at end of file diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/DrugbankHTMLParser.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/DrugbankHTMLParser.java index 07b0a36856c546256217932bd9e35d798fe7d083..6eac22a514f91a5b7401b74f6d7299ab144408fb 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/DrugbankHTMLParser.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/DrugbankHTMLParser.java @@ -9,6 +9,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.SerializationException; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -474,8 +475,12 @@ public class DrugbankHTMLParser extends DrugAnnotation implements IExternalServi @Override public Drug findDrug(String drugName) throws DrugSearchException { String query = DRUG_NAME_PREFIX + drugName; - - Drug drug = getDrugSerializer().xmlToObject(getCacheNode(query)); + Drug drug = null; + try { + drug = getDrugSerializer().xmlToObject(getCacheNode(query)); + } catch (SerializationException e) { + logger.error("Problem with deserializing element by query: " + query); + } if (drug != null) { return drug; } diff --git a/commons/src/main/java/lcsb/mapviewer/common/Configuration.java b/commons/src/main/java/lcsb/mapviewer/common/Configuration.java index a9c965f07410271f0914f1c2ff18796b4191e050..4db91ad32b813654ab30e0ec872690109f6c1398 100644 --- a/commons/src/main/java/lcsb/mapviewer/common/Configuration.java +++ b/commons/src/main/java/lcsb/mapviewer/common/Configuration.java @@ -67,6 +67,7 @@ public final class Configuration { * Where the main webpgae is located. */ public static final String MAIN_PAGE = "/index.xhtml"; + public static final String AUTH_TOKEN = "MINERVA_AUTH_TOKEN"; /** * Where miriam redirecting webpage is located. diff --git a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java index 0f0530880c2579459a31ce4729ed8ddf943dad6d..4df8104320ccd3743bcbc57472b3bd42ccc85d28 100644 --- a/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java +++ b/commons/src/main/java/lcsb/mapviewer/common/XmlParser.java @@ -210,7 +210,12 @@ public class XmlParser { protected Document getXmlDocumentFromString(final String text) throws InvalidXmlSchemaException { InputSource is = new InputSource(); is.setCharacterStream(new StringReader(text)); - return getXmlDocumentFromInputSource(is); + try { + return getXmlDocumentFromInputSource(is); + } catch (NullPointerException e) { + logger.error("Problem with input xml: " + text); + throw new InvalidXmlSchemaException(e); + } } /** diff --git a/frontend-js/src/main/js/Configuration.js b/frontend-js/src/main/js/Configuration.js new file mode 100644 index 0000000000000000000000000000000000000000..0db51c6fd0d623e28cbb530382879344b01d2ec4 --- /dev/null +++ b/frontend-js/src/main/js/Configuration.js @@ -0,0 +1,75 @@ +"use strict"; + +/* exported logger */ + +var logger = require('./logger'); + +var ConfigurationType = require('./ConfigurationType'); + +function Configuration(json) { + var self = this; + var i; + + self._options = []; + + for (i = 0; i < json.options.length; i++) { + var conf = json.options[i]; + var type = conf.type; + var value = conf.value; + self.setOption(type, value); + } + + var legendFiles = []; + if (self.getOption("LENGEND_FILE_1") !== undefined) { + legendFiles.push(self.getOption("LENGEND_FILE_1")); + } + if (self.getOption("LENGEND_FILE_2") !== undefined) { + legendFiles.push(self.getOption("LENGEND_FILE_2")); + } + if (self.getOption("LENGEND_FILE_3") !== undefined) { + legendFiles.push(self.getOption("LENGEND_FILE_3")); + } + if (self.getOption("LENGEND_FILE_4") !== undefined) { + legendFiles.push(self.getOption("LENGEND_FILE_4")); + } + self.setOption(ConfigurationType.LEGEND_FILES, legendFiles); + + var overlayTypes = []; + for (i = 0; i < json.overlayTypes.length; i++) { + overlayTypes.push(json.overlayTypes[i].name); + } + self.setOverlayTypes(overlayTypes); + + self.setImageConverters(json.imageFormats); + self.setModelConverters(json.modelFormats); +} + +Configuration.prototype.setOption = function(type, value) { + this._options[type] = value; +}; +Configuration.prototype.getOption = function(type) { + return this._options[type]; +}; + +Configuration.prototype.setOverlayTypes = function(overlayTypes) { + this._overlayTypes = overlayTypes; +}; +Configuration.prototype.getOverlayTypes = function() { + return this._overlayTypes; +}; + +Configuration.prototype.setImageConverters = function(imageConverters) { + this._imageConverters = imageConverters; +}; +Configuration.prototype.getImageConverters = function() { + return this._imageConverters; +}; + +Configuration.prototype.setModelConverters = function(modelConverters) { + this._modelConverters = modelConverters; +}; +Configuration.prototype.getModelConverters = function() { + return this._modelConverters; +}; + +module.exports = Configuration; diff --git a/frontend-js/src/main/js/Functions.js b/frontend-js/src/main/js/Functions.js index 7f6d092ee34328994961a82bd7069f4b41750424..14e71695de597639a821311fe11c0355169ccb25 100644 --- a/frontend-js/src/main/js/Functions.js +++ b/frontend-js/src/main/js/Functions.js @@ -166,52 +166,50 @@ Functions.isDomElement = function(o) { Functions.overlayToColor = function(elementOverlay) { var self = this; - return new Promise(function(resolve, reject) { - /* jslint bitwise: true */ - if (elementOverlay === null || elementOverlay === undefined) { - reject("elementOverlay cannot be null!"); - } else if (elementOverlay.color !== undefined && elementOverlay.color !== null) { - resolve(self.intToColorString(elementOverlay.color.value)); - } else if (elementOverlay.value !== undefined && elementOverlay.value !== null) { - var ratio = 0; - var promiseColor = null; - if (elementOverlay.value < 0) { - ratio = -elementOverlay.value; - promiseColor = ServerConnector.getMinOverlayColorInt(); - } else { - ratio = elementOverlay.value; - promiseColor = ServerConnector.getMaxOverlayColorInt(); - } - return promiseColor.then(function(color) { + /* jslint bitwise: true */ + if (elementOverlay === null || elementOverlay === undefined) { + return Promise.reject("elementOverlay cannot be null!"); + } else if (elementOverlay.color !== undefined && elementOverlay.color !== null) { + return Promise.resolve(self.intToColorString(elementOverlay.color.value)); + } else if (elementOverlay.value !== undefined && elementOverlay.value !== null) { + var ratio = 0; + var promiseColor = null; + if (elementOverlay.value < 0) { + ratio = -elementOverlay.value; + promiseColor = ServerConnector.getMinOverlayColorInt(); + } else { + ratio = elementOverlay.value; + promiseColor = ServerConnector.getMaxOverlayColorInt(); + } + return promiseColor.then(function(color) { - ratio = 1 - ratio; - var MAX_RED = 0xFF0000; - var MAX_GREEN = 0x00FF00; - var MAX_BLUE = 0x0000FF; + ratio = 1 - ratio; + var MAX_RED = 0xFF0000; + var MAX_GREEN = 0x00FF00; + var MAX_BLUE = 0x0000FF; - var red = color & MAX_RED; + var red = color & MAX_RED; - red = red + (MAX_RED - red) * ratio; - red = parseInt(red); - red = red & 0xFF0000; + red = red + (MAX_RED - red) * ratio; + red = parseInt(red); + red = red & 0xFF0000; - var green = color & MAX_GREEN; - green = green + (MAX_GREEN - green) * ratio; - green = parseInt(green); - green = green & MAX_GREEN; + var green = color & MAX_GREEN; + green = green + (MAX_GREEN - green) * ratio; + green = parseInt(green); + green = green & MAX_GREEN; - var blue = color & MAX_BLUE; - blue = blue + (MAX_BLUE - blue) * ratio; - blue = parseInt(blue); - blue = blue & MAX_BLUE; + var blue = color & MAX_BLUE; + blue = blue + (MAX_BLUE - blue) * ratio; + blue = parseInt(blue); + blue = blue & MAX_BLUE; - color = red | green | blue; - resolve(self.intToColorString(color)); - }); - } else { - reject("elementOverlay doesn't have neither color nor value set!"); - } - }); + color = red | green | blue; + return self.intToColorString(color); + }); + } else { + return Promise.reject("elementOverlay doesn't have neither color nor value set!"); + } }; Functions.getElementByName = function(element, name) { diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 3458d7ee8ac5ad75805bcccac9ab09e9a5d85844..eda59725674b3343729fb228ffdd417647a5178b 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -11,6 +11,7 @@ var request = require('request'); var Alias = require('./map/data/Alias'); var Chemical = require('./map/data/Chemical'); var Comment = require('./map/data/Comment'); +var Configuration = require('./Configuration'); var Drug = require('./map/data/Drug'); var ConfigurationType = require('./ConfigurationType'); var IdentifiedElement = require('./map/data/IdentifiedElement'); @@ -84,6 +85,10 @@ ServerConnector.readFile = function(url, description) { }).then(function(result) { content = result; return self.callListeners("onDataLoadStop", description); + }, function(error) { + return self.callListeners("onDataLoadStop", description).then(function() { + return Promise.reject(error); + }); }).then(function() { return content; }); @@ -96,7 +101,8 @@ ServerConnector._readFile = function(url) { reject(error); } else if (response.statusCode !== 200) { - reject(response); + var error = new Error(url + " rejected with status code: " + response.statusCode); + reject(error); } else { resolve(body); } @@ -114,7 +120,8 @@ ServerConnector.sendPostRequest = function(url, params) { reject(error); } else if (response.statusCode !== 200) { - reject(response); + var error = new Error(url + " rejected with status code: " + response.statusCode); + reject(error); } else { resolve(body); } @@ -131,7 +138,8 @@ ServerConnector.sendPutRequest = function(url, params) { if (error) { reject(error); } else if (response.statusCode !== 200) { - reject(response); + var error = new Error(url + " rejected with status code: " + response.statusCode); + reject(error); } else { resolve(body); } @@ -141,14 +149,35 @@ ServerConnector.sendPutRequest = function(url, params) { ServerConnector.sendDeleteRequest = function(url, params) { return new Promise(function(resolve, reject) { - request.del({ + request({ + method : "DELETE", url : url, - form : params + json : params, + }, function(error, response, body) { + if (error) { + reject(error); + } else if (response.statusCode !== 200) { + var error = new Error(url + " rejected with status code: " + response.statusCode); + reject(error); + } else { + resolve(body); + } + }); + }); +}; + +ServerConnector.sendPatchRequest = function(url, params) { + return new Promise(function(resolve, reject) { + request({ + method : "PATCH", + url : url, + json : params, }, function(error, response, body) { if (error) { reject(error); } else if (response.statusCode !== 200) { - reject(response); + var error = new Error(url + " rejected with status code: " + response.statusCode); + reject(error); } else { resolve(body); } @@ -156,19 +185,25 @@ ServerConnector.sendDeleteRequest = function(url, params) { }); }; -ServerConnector.getToken = function() { +ServerConnector.getToken = function(token) { + if (token !== undefined) { + return Promise.resolve(token); + } + var self = this; - var token = self.getSessionData(null).getToken(); + token = self.getSessionData(null).getToken(); if (token === undefined) { return self.login(); } else { + // if the project is not initialized then check if we can download data + // using current token if (self.getSessionData().getProject() === null) { - return self.isValidToken(token).then(function(isOk) { - if (isOk) { - return token; - } else { - return self.login(); - } + return self.getConfiguration({ + token : token + }).then(function() { + return token; + }, function() { + return self.login(); }); } else { return Promise.resolve(token); @@ -191,7 +226,7 @@ ServerConnector.getServerBaseUrl = function() { return this._serverBaseUrl; }; -ServerConnector.createGetParams = function(params) { +ServerConnector.createGetParams = function(params, prefix) { var sorted = [], key; for (key in params) { @@ -203,8 +238,25 @@ ServerConnector.createGetParams = function(params) { var result = ""; for (var i = 0; i < sorted.length; i++) { - if (params[sorted[i]] !== undefined) { - result += sorted[i] + "=" + params[sorted[i]] + "&"; + key = sorted[i]; + var value = params[key]; + if (prefix !== undefined) { + key = prefix + "." + key; + } + + if (value instanceof google.maps.Point) { + value = this.pointToString(value); + } else if (Object.prototype.toString.call(value) === '[object Array]') { + value = this.idsToString(value); + } else if (typeof value === 'string' || value instanceof String || !isNaN(value)) { + + } else { + result += this.createGetParams(value, key); + value = undefined; + } + + if (value !== undefined && value !== "") { + result += key + "=" + value + "&"; } } return result; @@ -215,195 +267,133 @@ ServerConnector.getApiUrl = function(paramObj) { var method = paramObj.method; var params = this.createGetParams(paramObj.params); - var result = this.getApiBaseUrl() + "/" + type + "/" + method; + var result = paramObj.url; + if (result === undefined) { + result = this.getApiBaseUrl() + "/" + type; + } + if (method !== undefined) { + result += "/" + method; + } if (params !== "") { result += "?" + params; } return result; }; -ServerConnector.getProjectUrl = function(projectId, token) { +ServerConnector.getProjectsUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "project", - method : "getMetaData", - params : { - projectId : projectId, - token : token, - }, + type : "projects/" + queryParams.projectId + "/", + params : filterParams, }); }; -ServerConnector.getImageConvertersUrl = function(params) { - return this.getApiUrl({ - type : "configuration", - method : "getImageFormats", - params : { - token : params.token, - }, - }); -}; -ServerConnector.getModelConvertersUrl = function(params) { +ServerConnector.getPublicationsUrl = function(queryParams, filterParams) { + filterParams.start = filterParams.start || 0; + filterParams.length = filterParams.length || 10; + return this.getApiUrl({ - type : "configuration", - method : "getModelFormats", - params : { - token : params.token, - }, + url : this.getModelsUrl(queryParams) + "publications/", + params : filterParams, }); }; -ServerConnector.getPublicationsUrl = function(params) { - var projectId = params.projectId; - var token = params.token; - var start = params.start || 0; - var length = params.length || 10; +ServerConnector.getReferenceGenomeUrl = function(queryParams, filterParams) { + var version = this.getIdOrAsterisk(queryParams.version); return this.getApiUrl({ - type : "project", - method : "getPublications", - params : { - projectId : projectId, - token : token, - start : start, - length : length, - }, + type : "genomics/taxonomies/" + queryParams.organism + "/types/" + queryParams.type + "/versions/" + version, + params : filterParams }); }; -ServerConnector.getReferenceGenomeUrl = function(params) { +ServerConnector.loginUrl = function() { return this.getApiUrl({ - type : "genomics", - method : "getReferenceGenome", - params : { - token : params.token, - type : params.type, - version : params.version, - organism : params.organism, - }, + type : "/doLogin", }); }; -ServerConnector.loginUrl = function() { +ServerConnector.getSuggestedQueryListUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "user", - method : "login" + url : this.getBioEntitiesUrl(queryParams) + "suggestedQueryList/", + params : filterParams, }); }; -ServerConnector.getSuggestedQueryListUrl = function(params) { +ServerConnector.addCommentUrl = function(queryParams) { return this.getApiUrl({ - type : "project", - method : "getSuggestedQueryList", - params : params, + url : this.getCommentsUrl(queryParams) }); }; -ServerConnector.addCommentUrl = function() { +ServerConnector.addOverlayUrl = function(queryParams) { return this.getApiUrl({ - type : "comment", - method : "addComment", + url : this.getOverlaysUrl(queryParams) }); }; -ServerConnector.addOverlayUrl = function() { +ServerConnector.updateOverlayUrl = function(queryParams) { return this.getApiUrl({ - type : "overlay", - method : "addOverlay", + url : this.getOverlayByIdUrl(queryParams) }); }; -ServerConnector.updateOverlayUrl = function() { +ServerConnector.deleteOverlayUrl = function(queryParams) { return this.getApiUrl({ - type : "overlay", - method : "updateOverlay", + url : this.getOverlayByIdUrl(queryParams), }); }; -ServerConnector.deleteOverlayUrl = function() { +ServerConnector.getOverlaysUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "overlay", - method : "removeOverlay", + url : this.getProjectsUrl(queryParams) + "overlays/", + params : filterParams, }); }; -ServerConnector.getOverlaysUrl = function(projectId, token) { +ServerConnector.getCommentsUrl = function(queryParams, filterParams) { + var modelId = this.getIdOrAsterisk(queryParams.modelId); + var url = this.getProjectsUrl(queryParams) + "comments/models/" + modelId + "/"; + if (queryParams.elementType !== undefined) { + if (queryParams.elementType === "ALIAS") { + url += "bioEntities/elements/" + queryParams.elementId; + } else if (queryParams.elementType === "REACTION") { + url += "bioEntities/reactions/" + queryParams.elementId; + } else if (queryParams.elementType === "POINT") { + url += "points/" + queryParams.coordinates; + } else { + throw new Error("Unknown element type: " + queryParams.elementType); + } + } return this.getApiUrl({ - type : "overlay", - method : "getOverlayList", - params : { - projectId : projectId, - token : token, - }, + url : url, + params : filterParams, }); }; -ServerConnector.getOverlayTypesUrl = function(params) { +ServerConnector.getOverlayByIdUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "overlay", - method : "getOverlayTypes", - params : { - token : params.token, - }, + url : this.getOverlaysUrl(queryParams) + queryParams.overlayId + "/", + params : filterParams, }); + }; -ServerConnector.getCommentsUrl = function(params) { - var elementId = params.elementId; - var elementType = params.elementType; - var columns = this.columnsToString(params.columns); - var projectId = params.projectId; - var token = params.token; +ServerConnector.getOverlayElementsUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "comment", - method : "getCommentList", - params : { - projectId : projectId, - columns : columns, - elementId : elementId, - elementType : elementType, - token : token - }, + url : this.getModelsUrl(queryParams) + "bioEntities/", + params : filterParams, }); -}; -ServerConnector.getOverlayByIdUrl = function(overlayId, projectId, token) { - return this.getApiUrl({ - type : "overlay", - method : "getOverlayById", - params : { - projectId : projectId, - token : token, - overlayId : overlayId, - }, - }); }; -ServerConnector.getOverlayElementsUrl = function(overlayId, projectId, token) { - return this.getApiUrl({ - type : "overlay", - method : "getOverlayElements", - params : { - projectId : projectId, - token : token, - overlayId : overlayId, - }, - }); -}; +ServerConnector.getFullOverlayElementUrl = function(queryParams, filterParams) { -ServerConnector.getFullOverlayElementUrl = function(params, token) { return this.getApiUrl({ - type : "overlay", - method : "getOverlayElement", - params : { - projectId : params.projectId, - token : token, - overlayId : params.overlay.getId(), - modelId : params.element.getModelId(), - elementId : params.element.getId(), - elementType : params.element.getType(), - }, + url : this.getAliasesUrl(queryParams) + queryParams.id + "/", + params : filterParams, }); + }; ServerConnector.idsToString = function(ids) { @@ -436,359 +426,149 @@ ServerConnector.columnsToString = function(columns) { return columns; }; -ServerConnector.getReactionsUrl = function(params) { - var id = this.idsToString(params.ids); - var columns = this.columnsToString(params.columns); - var participantId = this.idsToString(params.participantId); +ServerConnector.getModelsUrl = function(queryParams) { + var modelId = this.getIdOrAsterisk(queryParams.modelId); + var overlayId = queryParams.overlayId; + var url = this.getProjectsUrl(queryParams); + if (overlayId !== undefined) { + url = this.getOverlayByIdUrl(queryParams); + } return this.getApiUrl({ - type : "project", - method : "getReactions", - params : { - projectId : params.projectId, - token : params.token, - columns : columns, - id : id, - participantId : participantId, - }, + url : url + "models/" + modelId + "/", }); }; -ServerConnector.getAliasesUrl = function(params) { - var id = this.idsToString(params.ids); - var columns = this.columnsToString(params.columns); - var projectId = params.projectId; - var token = params.token; - +ServerConnector.getBioEntitiesUrl = function(queryParams) { return this.getApiUrl({ - type : "project", - method : "getElements", - params : { - projectId : projectId, - columns : columns, - id : id, - token : token - }, + url : this.getModelsUrl(queryParams) + "bioEntities/", }); }; -ServerConnector.getConfigurationUrl = function(token) { - var result = this.getApiUrl({ - type : "configuration", - method : "getAllValues", - params : { - token : token, - }, - }); - return result; +ServerConnector.getIdOrAsterisk = function(id) { + if (id === undefined || id === "" || id === null) { + return "*"; + } else { + return id; + } }; -ServerConnector.getClosestElementsByCoordinatesUrl = function(params) { - var coordinates = this.pointToString(params.coordinates); - var projectId = params.projectId; - var modelId = params.modelId; - var token = params.token; - var count = params.count; - +ServerConnector.getReactionsUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "project", - method : "getClosestElementsByCoordinates", - params : { - projectId : projectId, - coordinates : coordinates, - modelId : modelId, - count : count, - token : token - }, + url : this.getBioEntitiesUrl(queryParams) + "reactions/", + params : filterParams, }); }; -ServerConnector.getElementsByQueryUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - var perfectMatch = params.perfectMatch; - +ServerConnector.getAliasesUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "project", - method : "getElementsByQuery", - params : { - projectId : projectId, - query : query, - perfectMatch : perfectMatch, - token : token - }, + url : this.getBioEntitiesUrl(queryParams) + "elements/", + params : filterParams, }); }; -ServerConnector.getDrugsByQueryUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - - return this.getApiUrl({ - type : "drug", - method : "getDrugsByQuery", - params : { - projectId : projectId, - query : query, - token : token - }, +ServerConnector.getConfigurationUrl = function(queryParams, filterParams) { + var result = this.getApiUrl({ + type : "configuration/", + params : filterParams }); + return result; }; -ServerConnector.getDrugsByTargetUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - var columns = this.idsToString(params.columns); - var targetId = params.target.getId(); - var targetType = params.target.getType(); - +ServerConnector.getSearchUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "drug", - method : "getDrugsByTarget", - params : { - projectId : projectId, - query : query, - columns : columns, - token : token, - targetId : targetId, - targetType : targetType, - }, + url : this.getModelsUrl(queryParams) + "bioEntities:search", + params : filterParams, }); }; -ServerConnector.getMiRnasByQueryUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - +ServerConnector.getSearchDrugsUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "miRna", - method : "getMiRnasByQuery", - params : { - projectId : projectId, - query : query, - token : token - }, + url : this.getProjectsUrl(queryParams) + "drugs:search", + params : filterParams, }); }; -ServerConnector.getOverlaySourceUrl = function(params) { - var overlayId = params.overlayId; - var projectId = params.projectId; - var token = params.token; - - return this.getApiUrl({ - type : "overlay", - method : "getOverlaySource", - params : { - overlayId : overlayId, - projectId : projectId, - token : token - }, - }); -}; - -ServerConnector.getImageUrl = function(params) { - var projectId = params.projectId; - var token = params.token; - var polygonString = params.polygonString; - var modelId = params.modelId; - var handlerClass = params.handlerClass; - var backgroundOverlayId = params.backgroundOverlayId; - var zoomLevel = params.zoomLevel; - var overlayIds = this.idsToString(params.overlayIds); +ServerConnector.getSearchMiRnasUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "project", - method : "getModelAsImage", - params : { - polygonString : polygonString, - modelId : modelId, - handlerClass : handlerClass, - backgroundOverlayId : backgroundOverlayId, - zoomLevel : zoomLevel, - overlayIds : overlayIds, - projectId : projectId, - token : token, - }, - }); -}; - -ServerConnector.getModelPartUrl = function(params) { - var projectId = params.projectId; - var token = params.token; - var polygonString = params.polygonString; - var modelId = params.modelId; - var handlerClass = params.handlerClass; - var backgroundOverlayId = params.backgroundOverlayId; - var zoomLevel = params.zoomLevel; - var overlayIds = this.idsToString(params.overlayIds); - - return this.getApiUrl({ - type : "project", - method : "getModelAsModelFile", - params : { - polygonString : polygonString, - modelId : modelId, - handlerClass : handlerClass, - backgroundOverlayId : backgroundOverlayId, - zoomLevel : zoomLevel, - overlayIds : overlayIds, - projectId : projectId, - token : token, - }, + url : this.getProjectsUrl(queryParams) + "miRnas:search", + params : filterParams, }); }; -ServerConnector.getProjectSourceUrl = function(params) { - var projectId = params.projectId; - var token = params.token; - +ServerConnector.getSearchChemicalsUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "project", - method : "getProjectSource", - params : { - projectId : projectId, - token : token - }, + url : this.getProjectsUrl(queryParams) + "chemicals:search", + params : filterParams, }); }; -ServerConnector.getMiRnasByTargetUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - var columns = this.idsToString(params.columns); - var targetId = params.target.getId(); - var targetType = params.target.getType(); - +ServerConnector.getOverlaySourceUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "miRna", - method : "getMiRnasByTarget", - params : { - projectId : projectId, - query : query, - columns : columns, - token : token, - targetId : targetId, - targetType : targetType, - }, + url : this.getOverlaysUrl(queryParams) + queryParams.overlayId + ":downloadSource", + params : filterParams }); }; -ServerConnector.getChemicalsByQueryUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - +ServerConnector.getImageUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "chemical", - method : "getChemicalsByQuery", - params : { - projectId : projectId, - query : query, - token : token - }, + url : this.getProjectsUrl(queryParams) + "models/" + queryParams.modelId + ":downloadImage", + params : filterParams, }); }; -ServerConnector.getChemicalsByTargetUrl = function(params) { - var query = params.query; - var projectId = params.projectId; - var token = params.token; - var columns = this.idsToString(params.columns); - var targetId = params.target.getId(); - var targetType = params.target.getType(); - +ServerConnector.getModelPartUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "chemical", - method : "getChemicalsByTarget", - params : { - projectId : projectId, - query : query, - columns : columns, - token : token, - targetId : targetId, - targetType : targetType, - }, + url : this.getProjectsUrl(queryParams) + "models/" + queryParams.modelId + ":downloadModel", + params : filterParams, }); }; -ServerConnector.getUserUrl = function(params) { - var userId = params.userId; - var token = params.token; - +ServerConnector.getProjectSourceUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "user", - method : "getUser", - params : { - userId : userId, - token : token, - }, + type : "projects/" + queryParams.projectId + ":downloadSource", + params : filterParams }); }; -ServerConnector.isValidTokenUrl = function(params) { - var token = params.token; - +ServerConnector.getUserUrl = function(queryParams, filterParams) { return this.getApiUrl({ - type : "user", - method : "tokenStatus", - params : { - token : token, - }, + type : "users/", + method : queryParams.login, + params : filterParams, }); }; -ServerConnector.getConfigurationParam = function(paramId) { +ServerConnector.getConfiguration = function(params) { + if (params === undefined) { + params = {}; + } var self = this; - if (paramId === undefined) { - return Promise.reject(new Error("Invalid param identifier")); - } else if (self._configurationParam[paramId] !== undefined) { - return Promise.resolve(self._configurationParam[paramId]); - } else { - return self.getToken().then(function(token) { - return self.readFile(self.getConfigurationUrl(token)); - }).then(function(content) { - var configs = JSON.parse(content); - for (var i = 0; i < configs.length; i++) { - var conf = configs[i]; - var type = conf.type; - var value = conf.value; - self._configurationParam[type] = value; - } - - self._configurationParam[ConfigurationType.LEGEND_FILES] = []; - if (self._configurationParam["LENGEND_FILE_1"] !== undefined) { - self._configurationParam[ConfigurationType.LEGEND_FILES].push(self._configurationParam["LENGEND_FILE_1"]); - } - if (self._configurationParam["LENGEND_FILE_2"] !== undefined) { - self._configurationParam[ConfigurationType.LEGEND_FILES].push(self._configurationParam["LENGEND_FILE_2"]); - } - if (self._configurationParam["LENGEND_FILE_3"] !== undefined) { - self._configurationParam[ConfigurationType.LEGEND_FILES].push(self._configurationParam["LENGEND_FILE_3"]); - } - if (self._configurationParam["LENGEND_FILE_4"] !== undefined) { - self._configurationParam[ConfigurationType.LEGEND_FILES].push(self._configurationParam["LENGEND_FILE_4"]); - } - if (self._configurationParam[paramId] === undefined) { - Promise.reject(new Error("Cannot find param config: " + paramId)); - } - return self._configurationParam[paramId]; + if (this._configuration === undefined) { + return self.readFile(self.getConfigurationUrl()).then(function(content) { + self._configuration = new Configuration(JSON.parse(content)); + return Promise.resolve(self._configuration); }); + } else { + return Promise.resolve(self._configuration); } }; +ServerConnector.getConfigurationParam = function(paramId) { + var self = this; + return self.getConfiguration().then(function(configuration) { + return configuration.getOption(paramId); + }); +}; + ServerConnector.getProject = function(projectId) { + var queryParams = {}; + var filterParams = {}; var project; var self = this; return self.getProjectId(projectId).then(function(result) { - projectId = result; - return self.getToken(); - }).then(function(token) { - return self.readFile(self.getProjectUrl(projectId, token)); + queryParams.projectId = result; + return self.readFile(self.getProjectsUrl(queryParams, filterParams)); }).then(function(content) { project = new Project(content); return self.getOverlays(projectId); @@ -803,21 +583,21 @@ ServerConnector.getLoggedUser = function() { if (self._loggedUser !== undefined) { return Promise.resolve(self._loggedUser); } else { - return self.getUser().then(function(user) { + return self.getUser(self.getSessionData().getLogin()).then(function(user) { self._loggedUser = user; return self._loggedUser; }); } }; -ServerConnector.getUser = function(userId) { +ServerConnector.getUser = function(login) { var self = this; - return self.getToken().then(function(token) { - return self.readFile(self.getUserUrl({ - token : token, - userId : userId - })); - }).then(function(content) { + var queryParams = { + login : login, + }; + var filterParams = {}; + + return self.readFile(self.getUserUrl(queryParams, filterParams)).then(function(content) { var obj = JSON.parse(content); return new User(obj); }); @@ -825,12 +605,12 @@ ServerConnector.getUser = function(userId) { ServerConnector.getOverlays = function(projectId) { var self = this; + var queryParams = {}; + var filterParams = {}; return new Promise(function(resolve, reject) { self.getProjectId(projectId).then(function(result) { - projectId = result; - return self.getToken(); - }).then(function(token) { - return self.readFile(self.getOverlaysUrl(projectId, token)); + queryParams.projectId = result; + return self.readFile(self.getOverlaysUrl(queryParams, filterParams)); }).then(function(content) { var arr = JSON.parse(content); var result = []; @@ -848,14 +628,14 @@ ServerConnector.getOverlayElements = function(overlayId, projectId) { if (overlayId === undefined) { throw new Error("Layout id must be defined"); } - - var token = null; - return self.getToken().then(function(result) { - token = result; - return self.getProjectId(projectId); - }).then(function(result) { - projectId = result; - return self.readFile(self.getOverlayElementsUrl(overlayId, projectId, token)); + var queryParams = { + overlayId : overlayId, + modelId : "*", + }; + var filterParams = {}; + return self.getProjectId(projectId).then(function(result) { + queryParams.projectId = result; + return self.readFile(self.getOverlayElementsUrl(queryParams, filterParams)); }).then(function(content) { var arr = JSON.parse(content); var result = []; @@ -875,14 +655,17 @@ ServerConnector.getOverlayElements = function(overlayId, projectId) { ServerConnector.getFullOverlayElement = function(params) { var self = this; - var token = null; - return self.getToken().then(function(result) { - token = result; - return self.getProjectId(params.projectId); - }).then(function(result) { - params.projectId = result; - return self.readFile(self.getFullOverlayElementUrl(params, token)); + var queryParams = { + overlayId : params.overlay.getId(), + modelId : params.element.getModelId(), + id : params.element.getId(), + }; + var filterParams = {}; + + return self.getProjectId(params.projectId).then(function(result) { + queryParams.projectId = result; + return self.readFile(self.getFullOverlayElementUrl(queryParams, filterParams)); }).then(function(content) { var element = JSON.parse(content); var result = null; @@ -920,13 +703,15 @@ ServerConnector.getMaxSearchDistance = function() { return this.getConfigurationParam(ConfigurationType.SEARCH_DISTANCE); }; -ServerConnector.getOverlayById = function(layoutId, projectId) { +ServerConnector.getOverlayById = function(overlayId, projectId) { var self = this; + var queryParams = { + overlayId : overlayId + }; + var filterParams = {}; return self.getProjectId(projectId).then(function(data) { - projectId = data; - return self.getToken(); - }).then(function(token) { - return self.readFile(self.getOverlayByIdUrl(layoutId, projectId, token)); + queryParams.projectId = data; + return self.readFile(self.getOverlayByIdUrl(queryParams, filterParams)); }).then(function(content) { return new LayoutData(JSON.parse(content)); }); @@ -934,12 +719,15 @@ ServerConnector.getOverlayById = function(layoutId, projectId) { ServerConnector.getReactions = function(params) { var self = this; + var queryParams = {}; + var filterParams = { + id : params.ids, + columns : params.columns, + participantId : params.participantId, + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getReactionsUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getReactionsUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -952,16 +740,14 @@ ServerConnector.getReactions = function(params) { ServerConnector.getAliases = function(aliasIds, projectId, columns) { var self = this; + var queryParams = {}; + var filterParams = { + id : aliasIds, + columns : columns + }; return self.getProjectId(projectId).then(function(result) { - projectId = result; - return self.getToken(); - }).then(function(token) { - return self.readFile(self.getAliasesUrl({ - ids : aliasIds, - projectId : projectId, - token : token, - columns : columns - })); + queryParams.projectId = result; + return self.readFile(self.getAliasesUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -979,12 +765,16 @@ ServerConnector.getLightComments = function(params) { ServerConnector.getComments = function(params) { var self = this; + var queryParams = { + elementId : params.elementId, + elementType : params.elementType, + }; + var filterParams = { + columns : params.columns + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getCommentsUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getCommentsUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1011,12 +801,16 @@ ServerConnector.getSessionData = function(project) { ServerConnector.getClosestElementsByCoordinates = function(params) { var self = this; + var queryParams = { + modelId : params.modelId + }; + var filterParams = { + coordinates : params.coordinates, + count : params.count, + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getClosestElementsByCoordinatesUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1029,55 +823,39 @@ ServerConnector.getClosestElementsByCoordinates = function(params) { ServerConnector.login = function(login, password) { var self = this; - return new Promise(function(resolve, reject) { - var params = {}; - if (login !== undefined) { - params.login = login; - params.password = password; - } else { - params.login = "anonymous"; - } - return self.sendPostRequest(self.loginUrl(), params).then(function(content) { - var obj = JSON.parse(content); - var token = obj.id; - if (token === undefined) { - reject(obj.error); - } else { - self.getSessionData().setToken(token); - resolve(token); - } - }); - }); -}; - -ServerConnector.isValidToken = function(token) { - var self = this; - return new Promise(function(resolve) { - return self.readFile(self.isValidTokenUrl({ - token : token - })).then(function(content) { - var obj = JSON.parse(content); - resolve(obj.error === undefined); - }, function() { - resolve(false); - }); + var params = {}; + if (login !== undefined) { + params.login = login; + params.password = password; + } else { + params.login = "anonymous"; + } + return self.sendPostRequest(self.loginUrl(), params).then(function() { + self.getSessionData().setLogin(params.login); + return Promise.resolve(self.getSessionData().getToken()); }); }; ServerConnector.logout = function() { var self = this; self.getSessionData().setToken(undefined); + self.getSessionData().setLogin(undefined); return Promise.resolve(); }; ServerConnector.getElementsByQuery = function(params) { var self = this; + var queryParams = { + modelId : params.modelId + }; + var filterParams = { + query : params.query, + perfectMatch : params.perfectMatch, + }; + return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getElementsByQueryUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1090,12 +868,13 @@ ServerConnector.getElementsByQuery = function(params) { ServerConnector.getDrugsByQuery = function(params) { var self = this; + var queryParams = {}; + var filterParams = { + query : params.query + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getDrugsByQueryUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchDrugsUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1108,12 +887,13 @@ ServerConnector.getDrugsByQuery = function(params) { ServerConnector.getMiRnasByQuery = function(params) { var self = this; + var queryParams = {}; + var filterParams = { + query : params.query + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getMiRnasByQueryUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchMiRnasUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1126,12 +906,13 @@ ServerConnector.getMiRnasByQuery = function(params) { ServerConnector.getChemicalsByQuery = function(params) { var self = this; + var queryParams = {}; + var filterParams = { + query : params.query + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getChemicalsByQueryUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchChemicalsUrl(queryParams, filterParams)); }).then(function(content) { var array = JSON.parse(content); var result = []; @@ -1144,59 +925,67 @@ ServerConnector.getChemicalsByQuery = function(params) { ServerConnector.getOverlaySourceDownloadUrl = function(params) { var self = this; + var queryParams = { + overlayId : params.overlayId + }; + var filterParams = {}; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.getOverlaySourceUrl(params); + queryParams.projectId = result; + return self.getOverlaySourceUrl(queryParams, filterParams); }); }; ServerConnector.getImageDownloadUrl = function(params) { var self = this; + var queryParams = { + projectId : params.projectId, + modelId : params.modelId, + }; + var filterParams = { + token : params.token, + polygonString : params.polygonString, + handlerClass : params.handlerClass, + backgroundOverlayId : params.backgroundOverlayId, + zoomLevel : params.zoomLevel, + overlayIds : this.idsToString(params.overlayIds), + }; + return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.getImageUrl(params); + queryParams.projectId = result; + return self.getImageUrl(queryParams, filterParams); }); }; ServerConnector.getModelDownloadUrl = function(params) { var self = this; + var queryParams = { + projectId : params.projectId, + modelId : params.modelId, + }; + var filterParams = { + token : params.token, + polygonString : params.polygonString, + handlerClass : params.handlerClass, + backgroundOverlayId : params.backgroundOverlayId, + zoomLevel : params.zoomLevel, + overlayIds : this.idsToString(params.overlayIds), + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.getModelPartUrl(params); + queryParams.projectId = result; + return self.getModelPartUrl(queryParams, filterParams); }); }; -ServerConnector.getImageConverters = function(params) { - if (params === undefined) { - params = {}; - } +ServerConnector.getImageConverters = function() { var self = this; - return self.getToken().then(function(token) { - params.token = token; - return self.readFile(self.getImageConvertersUrl(params)); - }).then(function(content) { - return JSON.parse(content); + return self.getConfiguration().then(function(configuration) { + return configuration.getImageConverters(); }); }; -ServerConnector.getModelConverters = function(params) { - if (params === undefined) { - params = {}; - } +ServerConnector.getModelConverters = function() { var self = this; - return self.getToken().then(function(token) { - params.token = token; - return self.readFile(self.getModelConvertersUrl(params)); - }).then(function(content) { - return JSON.parse(content); + return self.getConfiguration().then(function(configuration) { + return configuration.getModelConverters(); }); }; @@ -1204,25 +993,25 @@ ServerConnector.getProjectSourceDownloadUrl = function(params) { if (params === undefined) { params = {}; } + var queryParams = {}; + var filterParams = {}; var self = this; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.getProjectSourceUrl(params); + queryParams.projectId = result; + return self.getProjectSourceUrl(queryParams, filterParams); }); }; ServerConnector.getDrugNamesByTarget = function(params) { var self = this; - params.columns = [ "name" ]; + var queryParams = {}; + var filterParams = { + columns : [ "name" ], + target : params.target.getType() + ":" + params.target.getId() + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getDrugsByTargetUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchDrugsUrl(queryParams, filterParams)); }).then(function(content) { var result = []; var object = JSON.parse(content); @@ -1235,13 +1024,14 @@ ServerConnector.getDrugNamesByTarget = function(params) { ServerConnector.getMiRnaNamesByTarget = function(params) { var self = this; - params.columns = [ "name" ]; + var queryParams = {}; + var filterParams = { + columns : [ "name" ], + target : params.target.getType() + ":" + params.target.getId() + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getMiRnasByTargetUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchMiRnasUrl(queryParams, filterParams)); }).then(function(content) { var result = []; var object = JSON.parse(content); @@ -1254,13 +1044,14 @@ ServerConnector.getMiRnaNamesByTarget = function(params) { ServerConnector.getChemicalNamesByTarget = function(params) { var self = this; - params.columns = [ "name" ]; + var queryParams = {}; + var filterParams = { + columns : [ "name" ], + target : params.target.getType() + ":" + params.target.getId() + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getChemicalsByTargetUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getSearchChemicalsUrl(queryParams, filterParams)); }).then(function(content) { var result = []; var object = JSON.parse(content); @@ -1273,82 +1064,70 @@ ServerConnector.getChemicalNamesByTarget = function(params) { ServerConnector.addComment = function(params) { var self = this; - return new Promise(function(resolve, reject) { - return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - params.coordinates = self.pointToString(params.coordinates); - return self.sendPostRequest(self.addCommentUrl(), params); - }).then(function(content) { - var response = JSON.parse(content); - if (response.status === "OK") { - resolve(); - } else { - reject(response); - } - }); + var queryParams = { + elementId : params.elementId, + elementType : params.elementType, + coordinates : self.pointToString(params.coordinates), + modelId : params.modelId, + }; + var filterParams = params; + delete filterParams.elementId; + delete filterParams.elementType; + if (queryParams.elementType === "POINT") { + delete filterParams.coordinates; + } else { + filterParams.coordinates = self.pointToString(params.coordinates); + } + delete filterParams.modelId; + return self.getProjectId(params.projectId).then(function(result) { + queryParams.projectId = result; + return self.sendPostRequest(self.addCommentUrl(queryParams), filterParams); + }).then(function(content) { + var response = JSON.parse(content); + return new Comment(response); }); }; ServerConnector.addOverlay = function(params) { var self = this; - return new Promise(function(resolve, reject) { - return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.sendPostRequest(self.addOverlayUrl(), params); - }).then(function(content) { - var response = JSON.parse(content); - if (response.status === "OK") { - resolve(response.overlayId); - } else { - reject(response); - } - }); + var queryParams = {}; + return self.getProjectId(params.projectId).then(function(result) { + queryParams.projectId = result; + return self.sendPostRequest(self.addOverlayUrl(queryParams), params); + }).then(function(content) { + return new LayoutData(JSON.parse(content)); }); }; ServerConnector.updateOverlay = function(params) { var self = this; - return new Promise(function(resolve, reject) { - return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.sendPostRequest(self.updateOverlayUrl(), params); - }).then(function(content) { - var response = JSON.parse(content); - if (response.status === "OK") { - resolve(); - } else { - reject(response.reason); - } - }); + var queryParams = { + overlayId : params.overlayId + }; + var filterParams = { + overlay : {} + }; + if (params.name !== undefined) { + filterParams.overlay.name = params.name; + } + if (params.description !== undefined) { + filterParams.overlay.description = params.description; + } + return self.getProjectId(params.projectId).then(function(result) { + queryParams.projectId = result; + return self.sendPatchRequest(self.updateOverlayUrl(queryParams), filterParams); }); }; ServerConnector.removeOverlay = function(params) { var self = this; - return new Promise(function(resolve, reject) { - return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.sendPostRequest(self.deleteOverlayUrl(), params); - }).then(function(content) { - var response = JSON.parse(content); - if (response.status === "OK") { - resolve(); - } else { - reject(response); - } - }); + var queryParams = { + overlayId : params.overlayId + }; + var filterParams = {}; + return self.getProjectId(params.projectId).then(function(result) { + queryParams.projectId = result; + return self.sendDeleteRequest(self.deleteOverlayUrl(queryParams), filterParams); }); }; @@ -1356,12 +1135,9 @@ ServerConnector.getSuggestedQueryList = function(projectId) { var self = this; return self.getProjectId(projectId).then(function(result) { projectId = result; - return self.getToken(); - }).then(function(token) { - return self.sendPostRequest(self.getSuggestedQueryListUrl(), { - projectId : projectId, - token : token - }); + return self.readFile(self.getSuggestedQueryListUrl({ + projectId : projectId + })); }).then(function(content) { return JSON.parse(content); }); @@ -1369,17 +1145,8 @@ ServerConnector.getSuggestedQueryList = function(projectId) { ServerConnector.getOverlayTypes = function() { var self = this; - return self.getToken().then(function(token) { - return self.readFile(self.getOverlayTypesUrl({ - token : token - })); - }).then(function(content) { - var obj = JSON.parse(content); - var result = []; - for (var i = 0; i < obj.length; i++) { - result.push(obj[i].name); - } - return result; + return self.getConfiguration().then(function(configuration) { + return configuration.getOverlayTypes(); }); }; @@ -1388,12 +1155,15 @@ ServerConnector.getPublications = function(params) { if (params === undefined) { params = {}; } + + var queryParams = {}; + var filterParams = { + start : params.start, + length : params.length, + }; return self.getProjectId(params.projectId).then(function(result) { - params.projectId = result; - return self.getToken(); - }).then(function(token) { - params.token = token; - return self.readFile(self.getPublicationsUrl(params)); + queryParams.projectId = result; + return self.readFile(self.getPublicationsUrl(queryParams, filterParams)); }).then(function(content) { return JSON.parse(content); }); @@ -1401,10 +1171,8 @@ ServerConnector.getPublications = function(params) { ServerConnector.getReferenceGenome = function(params) { var self = this; - return self.getToken().then(function(token) { - params.token = token; - return self.readFile(self.getReferenceGenomeUrl(params)); - }).then(function(content) { + var filterParams = {}; + return self.readFile(self.getReferenceGenomeUrl(params, filterParams)).then(function(content) { return new ReferenceGenome(JSON.parse(content)); }); }; diff --git a/frontend-js/src/main/js/SessionData.js b/frontend-js/src/main/js/SessionData.js index 4a2c0f791f4c02610a300779be59990ee47b4080..08cc58aaa753c729c12878c1515258e71d5c1925 100644 --- a/frontend-js/src/main/js/SessionData.js +++ b/frontend-js/src/main/js/SessionData.js @@ -162,6 +162,21 @@ SessionData.prototype.getToken = function() { return value; }; +SessionData.prototype.setLogin = function(login) { + var key = SessionObjectType.LOGIN; + if (login === undefined) { + Cookies.remove(key); + } else { + Cookies.set(key, login); + } +}; + +SessionData.prototype.getLogin = function() { + var key = SessionObjectType.LOGIN; + var value = Cookies.get(key); + return value; +}; + SessionData.prototype.setCenter = function(model, value) { var key = this.getKey(SessionObjectType.CENTER, [ model.getId() ]); Cookies.set(key, value.x + "," + value.y); diff --git a/frontend-js/src/main/js/SessionObjectType.js b/frontend-js/src/main/js/SessionObjectType.js index db2936af619546a4cca3194a042d7d6853471767..1464e5b946d5b07b2aa5d10b7a9a21d19d65da08 100644 --- a/frontend-js/src/main/js/SessionObjectType.js +++ b/frontend-js/src/main/js/SessionObjectType.js @@ -12,7 +12,8 @@ var SessionObjectType = { CENTER : "CENTER", ZOOM_LEVEL : "ZOOM_LEVEL", - TOKEN: "TOKEN", + TOKEN: "MINERVA_AUTH_TOKEN", + LOGIN: "LOGIN", }; module.exports = SessionObjectType; diff --git a/frontend-js/src/main/js/gui/CommentDialog.js b/frontend-js/src/main/js/gui/CommentDialog.js index c1391876f6ee97b5de7f8702998937a6ee9863d3..c8781eabda6c102a9b054da8275e403ac7cc2438 100644 --- a/frontend-js/src/main/js/gui/CommentDialog.js +++ b/frontend-js/src/main/js/gui/CommentDialog.js @@ -1,5 +1,7 @@ "use strict"; +/* exported logger */ + var Promise = require("bluebird"); var AbstractGuiElement = require('./AbstractGuiElement'); @@ -108,12 +110,8 @@ CommentDialog.prototype._createGui = function() { var sendButton = document.createElement('button'); sendButton.innerHTML = "Send"; sendButton.onclick = function() { - self.addComment().then(function() { - if (self.close !== undefined) { - self.close(); - } else { - logger.warn("Cannot close dialog"); - } + return self.addComment().then(function() { + $(self.getElement()).dialog("close"); }); }; diff --git a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js index 3af19f332ae04132266da0066cba0c169101bd65..7d7d5d8b11225c1cfbbdd36afa6a4c86a43cb364 100644 --- a/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/OverlayPanel.js @@ -402,7 +402,8 @@ OverlayPanel.prototype.openAddOverlayDialog = function() { content : fileContent, filename : fileInput.value }; - return ServerConnector.addOverlay(data).then(function(){ + return ServerConnector.addOverlay(data).then(function(overlay){ + self.getMap().getModel().addLayout(overlay); return self.refresh(); }).then(function(){ $(dialog).dialog("close"); diff --git a/frontend-js/src/main/js/map/data/MapModel.js b/frontend-js/src/main/js/map/data/MapModel.js index ae53829cbe057e16b6f3de3e1a4fc4febeda79dc..89752b0ec15842d855cd10f2d96982ec4d4f7a4c 100644 --- a/frontend-js/src/main/js/map/data/MapModel.js +++ b/frontend-js/src/main/js/map/data/MapModel.js @@ -702,7 +702,7 @@ MapModel.prototype.isAvailable = function(ie, complete) { MapModel.prototype.getReactionsForElement = function(element, complete) { var self = this; if (this._reactionsByParticipantElementId[element.getId()]) { - var reactions = self._reactionsByParticipantElementId[element.getId()] + var reactions = self._reactionsByParticipantElementId[element.getId()]; if (!complete) { return Promise.resolve(reactions); } else { @@ -716,7 +716,7 @@ MapModel.prototype.getReactionsForElement = function(element, complete) { return ServerConnector.getReactions({ participantId : [ element.getId() ], }).then(function(reactions) { - var promises = [] + var promises = []; for (var i = 0; i < reactions.length; i++) { var reaction = reactions[i]; var id = reaction.getId(); @@ -728,7 +728,7 @@ MapModel.prototype.getReactionsForElement = function(element, complete) { promises.push(self.getReactionById(id, complete)); } return Promise.all(promises); - }) + }); }; module.exports = MapModel; diff --git a/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js b/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js index f7828221eff0799207f79afc178bdd9fc72750c0..fe99bfc0a4737d0d037af2e4bce4de427bf0a910 100644 --- a/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js +++ b/frontend-js/src/main/js/map/overlay/AbstractDbOverlay.js @@ -170,6 +170,7 @@ AbstractDbOverlay.prototype.searchByEncodedQuery = function(originalQuery, fitBo } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_TARGET) { return this.searchNamesByTarget(query.target); } else if (query.type === AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES) { + query.coordinates = new google.maps.Point(query.coordinates.x,query.coordinates.y); return this.searchByCoordinates(query); } else { throw new Error("Unknown type of query: " + query.type); diff --git a/frontend-js/src/main/js/map/window/AliasInfoWindow.js b/frontend-js/src/main/js/map/window/AliasInfoWindow.js index 2e10a2f56928c08e8f06dcbe557e75cd91645d43..1236a48328841c2ba8494dd54a132b4b09e404aa 100644 --- a/frontend-js/src/main/js/map/window/AliasInfoWindow.js +++ b/frontend-js/src/main/js/map/window/AliasInfoWindow.js @@ -285,6 +285,11 @@ AliasInfoWindow.prototype.createGenomicDiv = function() { logger.warn("Genome for " + variant.getReferenceGenomeType() + "," + variant.getReferenceGenomeVersion() + " not loaded"); } + }, + function() { + logger.warn("Genome for " + variant.getReferenceGenomeType() + "," + + variant.getReferenceGenomeVersion() + " not loaded"); + }); }); diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js index a217fa9a822c57c9165572a545c7bfb78fe64636..4d869f1aebd419ec7a50abcc912fcc135cedf16d 100644 --- a/frontend-js/src/main/js/minerva.js +++ b/frontend-js/src/main/js/minerva.js @@ -327,7 +327,10 @@ function create(params) { params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>" + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>"; - return getProject(params).then(function(project) { + //make sure that we are logged in + return ServerConnector.getToken().then(function(){ + return getProject(params); + }).then(function(project) { params.setProject(project); var element = params.getElement(); diff --git a/frontend-js/src/test/js/ServerConnector-mock.js b/frontend-js/src/test/js/ServerConnector-mock.js index fa21874b4c0b6fd08458d72bd669ab9da2649e10..03cbb59db4fe6ddde598cfaaafb4d86ec0fc248c 100644 --- a/frontend-js/src/test/js/ServerConnector-mock.js +++ b/frontend-js/src/test/js/ServerConnector-mock.js @@ -7,6 +7,7 @@ var Promise = require("bluebird"); var logger = require('./logger'); var OriginalServerConnector = require('../../main/js/ServerConnector'); +var SessionObjectType = require('../../main/js/SessionObjectType'); var fs = require('fs'); var request = require('request'); @@ -16,11 +17,28 @@ var ServerConnectorMock = OriginalServerConnector; ServerConnectorMock.init = function() { this._customMap = null; this._sessionData = undefined; + this._configuration = undefined; // add listener types }; ServerConnectorMock.init(); +function replaceAsterisk(str) { + return str.replace(/\*/g,"all").replace(/\:/g,"."); +} +function urlToFileName(url) { + var result = url; + var token = OriginalServerConnector.getSessionData().getToken(); + if (token!==undefined && url.startsWith("./testFiles/apiCalls")) { + if (!result.endsWith("&") &&!result.endsWith("_") ) { + result +="/"; + } + result+="token=" +token+"&"; + } + + return replaceAsterisk(result); +} + ServerConnectorMock._readFile = function(url) { return new Promise(function(resolve, reject) { if (url.indexOf("http") === 0) { @@ -34,7 +52,8 @@ ServerConnectorMock._readFile = function(url) { } }); } else { - fs.readFile(url, 'utf8', function(err, content) { + var fileName = urlToFileName(url); + fs.readFile(fileName, 'utf8', function(err, content) { if (err) { reject(err); } else { @@ -73,7 +92,7 @@ ServerConnectorMock.sendPostRequest = function(url, params) { } }); } else { - var mockUrl = url + "/" + self.createGetParams(encodeParams(params)); + var mockUrl = urlToFileName(url + "/POST_" + self.createGetParams(encodeParams(params))); fs.readFile(mockUrl, 'utf8', function(err, content) { if (err) { reject(err); @@ -103,7 +122,7 @@ ServerConnectorMock.sendPutRequest = function(url, params) { } }); } else { - var mockUrl = url + "/" + self.createGetParams(encodeParams(params)); + var mockUrl = urlToFileName(url + "/PUT_" + self.createGetParams(encodeParams(params))); fs.readFile(mockUrl, 'utf8', function(err, content) { if (err) { reject(err); @@ -133,12 +152,42 @@ ServerConnectorMock.sendDeleteRequest = function(url, params) { } }); } else { - var mockUrl = url + "/" + self.createGetParams(encodeParams(params)); + var mockUrl = urlToFileName(url + "/DELETE_" + self.createGetParams(encodeParams(params))); fs.readFile(mockUrl, 'utf8', function(err, content) { if (err) { reject(err); } else { - resolve(content); + resolve(JSON.parse(content)); + } + }); + } + }); +}; + +ServerConnectorMock.sendPatchRequest = function(url, params) { + var self = this; + return new Promise(function(resolve, reject) { + if (url.indexOf("http") === 0) { + request.delete({ + url : url, + form : params + }, function(error, response, body) { + if (error) { + reject(error); + + } else if (response.statusCode !== 200) { + reject(response); + } else { + resolve(body); + } + }); + } else { + var mockUrl = urlToFileName(url + "/PATCH_" + self.createGetParams(params)); + fs.readFile(mockUrl, 'utf8', function(err, content) { + if (err) { + reject(err); + } else { + resolve(JSON.parse(content)); } }); } diff --git a/frontend-js/src/test/js/ServerConnector-test.js b/frontend-js/src/test/js/ServerConnector-test.js index a7bae6073ea720936fac172a478e9c601c1cd083..8972e450c8a93799f84a46167a881c18e56bb894 100644 --- a/frontend-js/src/test/js/ServerConnector-test.js +++ b/frontend-js/src/test/js/ServerConnector-test.js @@ -3,6 +3,7 @@ require("./mocha-config.js"); var Alias = require('../../main/js/map/data/Alias'); +var Configuration = require('../../main/js/Configuration'); var LayoutAlias = require('../../main/js/map/data/LayoutAlias'); var Project = require('../../main/js/map/data/Project'); var Reaction = require('../../main/js/map/data/Reaction'); @@ -65,13 +66,13 @@ describe('ServerConnector', function() { }); it('getOverlayElements', function() { - return ServerConnector.getOverlayElements(101).then(function(result) { + return ServerConnector.getOverlayElements(18077).then(function(result) { assert.equal(result.length, 1); var layoutAlias = result[0]; assert.ok(layoutAlias instanceof LayoutAlias); - assert.equal(1.0, layoutAlias.getValue()); + assert.equal(-7602176, layoutAlias.getColor().value); assert.equal(15781, layoutAlias.getModelId()); - assert.equal(329173, layoutAlias.getId()); + assert.equal(329163, layoutAlias.getId()); }); }); @@ -82,15 +83,50 @@ describe('ServerConnector', function() { }); it('getOverlaySourceDownloadUrl', function() { - var id = 123; + var id = 17296; return ServerConnector.getOverlaySourceDownloadUrl({ overlayId : id }).then(function(url) { assert.ok(url); assert.ok(url.indexOf(id) >= 0); + return ServerConnector.readFile(url); }); }); + it('getImageDownloadUrl', function() { + var modelId = 15781; + return ServerConnector.getImageDownloadUrl({ + modelId : modelId, + handlerClass : "lcsb.mapviewer.converter.graphics.PngImageGenerator", + }).then(function(url) { + assert.ok(url); + assert.ok(url.indexOf(modelId) >= 0); + return ServerConnector.readFile(url); + }); + }); + + it('getModelDownloadUrl', function() { + var modelId = 15781; + return ServerConnector.getModelDownloadUrl({ + modelId : modelId, + handlerClass : "lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser", + }).then(function(url) { + assert.ok(url); + assert.ok(url.indexOf(modelId) >= 0); + return ServerConnector.readFile(url); + }); + }); + + it('getProjectSourceDownloadUrl', function() { + return ServerConnector.getProjectSourceDownloadUrl().then(function(url) { + assert.ok(url); + return ServerConnector.readFile(url); + }); + }); + + + + it('addOverlay', function() { return ServerConnector.addOverlay({ name : "test nam", @@ -116,13 +152,6 @@ describe('ServerConnector', function() { }); }); - it('getToken without login', function() { - ServerConnector.getSessionData().setToken(undefined); - return ServerConnector.getToken().then(function(token) { - assert.ok(token); - }); - }); - it('logout', function() { return ServerConnector.logout().then(function() { assert.equal(ServerConnector.getSessionData().getToken(), undefined); @@ -136,13 +165,17 @@ describe('ServerConnector', function() { assert.ok(url); }); }); - + it('getOverlayById', function() { - return ServerConnector.getOverlayById(90, "sample").then(function(overlay) { + return ServerConnector.getOverlayById(18083, "complex_model_with_submaps").then(function(overlay) { assert.ok(overlay); }); }); - - + + it('getConfiguration', function() { + return ServerConnector.getConfiguration().then(function(configuration) { + assert.ok(configuration instanceof Configuration); + }); + }); }); diff --git a/frontend-js/src/test/js/map/CustomMap-test.js b/frontend-js/src/test/js/map/CustomMap-test.js index 04c3644863806bc797a1cd5d1b76b44d5682f0f0..cb49a04241bfbfbf9010d95d3eb218d337c6990a 100644 --- a/frontend-js/src/test/js/map/CustomMap-test.js +++ b/frontend-js/src/test/js/map/CustomMap-test.js @@ -229,20 +229,17 @@ describe('CustomMap', function() { }); it("openInfoWindowForAlias for incomplete alias", function() { - var map = helper.createCustomMap(); - var layout = helper.createLayout(); - var alias = helper.createAlias(map); - alias.setId(30001); - alias.setIsComplete(false); - var layoutAlias = helper.createLayoutAlias(alias); - - layout.addAlias(layoutAlias); - - // create layout - map.getModel().addLayout(layout); - map.getModel().addAlias(alias); + var map, alias; + return ServerConnector.getProject().then(function(project) { + var options = helper.createCustomMapOptions(project); + map = new CustomMap(options); - return map.openInfoWindowForAlias(alias.getId(), map.getId(), function() { + return map.getModel().getAliasById(329171, false); + }).then(function(result) { + alias = result; + assert.notOk(alias.isComplete()); + return map.openInfoWindowForAlias(alias.getId(), map.getId()); + }).then(function() { assert.ok(map.getAliasInfoWindowById(alias.getId())); assert.ok(map.getAliasInfoWindowById(alias.getId()).isOpened()); }); @@ -673,12 +670,12 @@ describe('CustomMap', function() { it("openCommentDialog", function() { var map = helper.createCustomMap(); - map.getModel().setId(102); - map.setActiveSubmapId(102); + map.getModel().setId(15781); + map.setActiveSubmapId(15781); map.setActiveSubmapClickCoordinates(new google.maps.Point(2, 12)); return map.openCommentDialog().then(function() { var types = map.getCommentDialog().getTypes(); - assert.equal(types.length, 3); + assert.equal(types.length, 6); var selected = map.getCommentDialog().getSelectedType(); assert.ok(selected === "<General>"); @@ -696,8 +693,8 @@ describe('CustomMap', function() { it("addComment", function() { var map = helper.createCustomMap(); - map.getModel().setId(102); - map.setActiveSubmapId(102); + map.getModel().setId(15781); + map.setActiveSubmapId(15781); map.setActiveSubmapClickCoordinates(new google.maps.Point(2, 12)); return map.openCommentDialog().then(function() { return map.getCommentDialog().addComment(); @@ -706,6 +703,24 @@ describe('CustomMap', function() { }); }); + it("addComment for protein", function() { + var map; + var dialog; + return ServerConnector.getProject().then(function(project) { + var options = helper.createCustomMapOptions(project); + map = new CustomMap(options); + map.setActiveSubmapId(map.getId()); + map.setActiveSubmapClickCoordinates(new google.maps.Point(2, 12)); + return map.openCommentDialog(); + }).then(function() { + dialog = map.getCommentDialog(); + dialog.setSelectedType(1); + return dialog.addComment(); + }).then(function() { + map.getCommentDialog().destroy(); + }); + }); + it("retrieveOverlayDetailDataForElement for comment", function() { var map = helper.createCustomMap(); helper.createCommentDbOverlay(map); diff --git a/frontend-js/src/test/js/map/overlay/SearchDbOverlay-test.js b/frontend-js/src/test/js/map/overlay/SearchDbOverlay-test.js index 33e05fe2460f0ab55524fed5f931b2890c3c57bc..0b2c0291ec5a92e217ff22da5ca21f17b91d1654 100644 --- a/frontend-js/src/test/js/map/overlay/SearchDbOverlay-test.js +++ b/frontend-js/src/test/js/map/overlay/SearchDbOverlay-test.js @@ -6,6 +6,7 @@ var logger = require('../../logger'); var IdentifiedElement = require('../../../../main/js/map/data/IdentifiedElement'); var SearchDbOverlay = require('../../../../main/js/map/overlay/SearchDbOverlay'); +var AbstractDbOverlay = require('../../../../main/js/map/overlay/AbstractDbOverlay'); var assert = require('assert'); @@ -42,7 +43,21 @@ describe('SearchDbOverlay', function() { }).then(function(result) { assert.equal(result.length, 0); }); + }); + it("searchByEncodedQuery", function() { + return ServerConnector.getProject().then( + function(project) { + var map = helper.createCustomMap(project); + map.getModel().setId(15781); + var searchDb = helper.createSearchDbOverlay(map); + + var query = searchDb.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_COORDINATES, map.getModel().getId(), + new google.maps.Point(316.05, 253.61), 2); + return searchDb.searchByEncodedQuery(query); + }).then(function(result) { + assert.ok(result.length > 0); + }); }); it("searchByCoordinates with too far reaction as result", function() { diff --git a/frontend-js/src/test/js/map/window/AliasInfoWindow-test.js b/frontend-js/src/test/js/map/window/AliasInfoWindow-test.js index 9c1fa68c54ce4013aa74dad99aee31b5e2a3a358..aaa64afa129b881f6b3a001f02abb3cfb0823721 100644 --- a/frontend-js/src/test/js/map/window/AliasInfoWindow-test.js +++ b/frontend-js/src/test/js/map/window/AliasInfoWindow-test.js @@ -158,6 +158,38 @@ describe('AliasInfoWindow', function() { return win.createGenomicDiv(); }).then(function(div) { assert.ok(div); + assert.ok(div.innerHTML.indexOf("No reference genome data available on minerva platform") === -1); + win.destroy(); + }); + + }); + + it("createGeneticsDivForUnknownOrganism", function() { + var map; + var overlay; + + var layoutAlias; + var win; + + return ServerConnector.getProject().then(function(project) { + project.getOrganism().name = "123456"; + map = helper.createCustomMap(project); + overlay = new LayoutData(18077, "xxx"); + return overlay.init(); + }).then(function() { + return overlay.getFullAliasById(overlay.getAliases()[0].getId()); + }).then(function(data) { + layoutAlias = data; + return map.getModel().getAliasById(layoutAlias.getId()); + }).then(function(alias) { + win = new AliasInfoWindow(alias, map); + return win.init(); + }).then(function() { + win.layoutAliases = [ layoutAlias ]; + return win.createGenomicDiv(); + }).then(function(div) { + assert.ok(div); + assert.ok(div.innerHTML.indexOf("No reference genome data available on minerva platform") >= -1); win.destroy(); }); diff --git a/frontend-js/src/test/js/mocha-config.js b/frontend-js/src/test/js/mocha-config.js index 9267f8971083fd37b4e436283281ec2d59bea323..1e001a4b2eac4d80e33812d93cf378d99fc1c5e0 100644 --- a/frontend-js/src/test/js/mocha-config.js +++ b/frontend-js/src/test/js/mocha-config.js @@ -10,7 +10,7 @@ global.navigator = { userAgent : 'node.js', appName : 'MinervaUnitTest', appVersion : '0.0.1', - + }; var jsdom = require('jsdom'); @@ -91,6 +91,7 @@ beforeEach(function() { ServerConnector.init(); ServerConnector.getSessionData(null).setToken("MOCK_TOKEN_ID"); + ServerConnector.getSessionData(null).setLogin("anonymous"); GuiConnector.init(); diff --git a/frontend-js/testFiles/apiCalls/comment/addComment/content=&coordinates=2.00%2C12.00&elementId=&elementType=POINT&email=&modelId=102&name=&pinned=false&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/comment/addComment/content=&coordinates=2.00%2C12.00&elementId=&elementType=POINT&email=&modelId=102&name=&pinned=false&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 48aa9beb26c0c790cee15c8f721b3a10cf95a5fb..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/comment/addComment/content=&coordinates=2.00%2C12.00&elementId=&elementType=POINT&email=&modelId=102&name=&pinned=false&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -{"status":"OK"} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/configuration/getAllValues/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/configuration/getAllValues/token=MOCK_TOKEN_ID& deleted file mode 100644 index a027ad2bf1a9ed163cee0f993694a3ff681139f0..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/configuration/getAllValues/token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"type":"EMAIL_ADDRESS","value":"your.account@domain.com","idObject":9},{"type":"EMAIL_LOGIN","value":"your@login","idObject":10},{"type":"EMAIL_PASSWORD","value":"email.secret.password","idObject":11},{"type":"EMAIL_IMAP_SERVER","value":"your.imap.domain.com","idObject":13},{"type":"EMAIL_SMTP_SERVER","value":"your.smtp.domain.com","idObject":12},{"type":"EMAIL_SMTP_PORT","value":"25","idObject":14},{"type":"DEFAULT_MAP","value":"sample","idObject":6},{"type":"LOGO_IMG","value":"udl.png","idObject":4},{"type":"LOGO_LINK","value":"http://wwwen.uni.lu/","idObject":3},{"type":"SEARCH_DISTANCE","value":"10","idObject":7},{"type":"REQUEST_ACCOUNT_EMAIL","value":"your.email@domain.com","idObject":1},{"type":"SEARCH_RESULT_NUMBER","value":"100","idObject":8},{"type":"GOOGLE_ANALYTICS_IDENTIFIER","value":"google_analytics_id","idObject":2},{"type":"LOGO_TEXT","value":"University of Luxembourg","idObject":5},{"type":"X_FRAME_DOMAIN","value":"http://localhost:8080/","idObject":56},{"type":"BIG_FILE_STORAGE_DIR","value":"minerva-big/","idObject":131},{"type":"LENGEND_FILE_1","value":"resources/images/legend_a.png","idObject":138},{"type":"LENGEND_FILE_2","value":"resources/images/legend_b.png","idObject":139},{"type":"LENGEND_FILE_3","value":"resources/images/legend_c.png","idObject":140},{"type":"LENGEND_FILE_4","value":"resources/images/legend_d.png","idObject":141},{"type":"USER_MANUAL_FILE","value":"resources/other/user_guide.pdf","idObject":142},{"type":"MIN_COLOR_VAL","value":"FF0000","idObject":205},{"type":"MAX_COLOR_VAL","value":"fbff00","idObject":206}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/configuration/getImageFormats/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/configuration/getImageFormats/token=MOCK_TOKEN_ID& deleted file mode 100644 index 72573aadef036520aba0d3c9537467a882ab9e39..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/configuration/getImageFormats/token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"handler":"lcsb.mapviewer.converter.graphics.PngImageGenerator","name":"PNG image"},{"handler":"lcsb.mapviewer.converter.graphics.PdfImageGenerator","name":"PDF"}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/configuration/getModelFormats/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/configuration/getModelFormats/token=MOCK_TOKEN_ID& deleted file mode 100644 index 72ccb394d6f8afdf66768b691d2e0ba7f616e530..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/configuration/getModelFormats/token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"handler":"lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser","name":"CellDesigner SBML"},{"handler":"lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter","name":"SBGN-ML"}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..0ce74643e1400a4a870c959c2757e4fa5b1b43e1 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/configuration/token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"modelFormats":[{"handler":"lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser","name":"CellDesigner SBML"},{"handler":"lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter","name":"SBGN-ML"}],"imageFormats":[{"handler":"lcsb.mapviewer.converter.graphics.PngImageGenerator","name":"PNG image"},{"handler":"lcsb.mapviewer.converter.graphics.PdfImageGenerator","name":"PDF"}],"options":[{"idObject":9,"type":"EMAIL_ADDRESS","value":"your.account@domain.com"},{"idObject":10,"type":"EMAIL_LOGIN","value":"your@login"},{"idObject":11,"type":"EMAIL_PASSWORD","value":"email.secret.password"},{"idObject":13,"type":"EMAIL_IMAP_SERVER","value":"your.imap.domain.com"},{"idObject":12,"type":"EMAIL_SMTP_SERVER","value":"your.smtp.domain.com"},{"idObject":14,"type":"EMAIL_SMTP_PORT","value":"25"},{"idObject":6,"type":"DEFAULT_MAP","value":"sample"},{"idObject":4,"type":"LOGO_IMG","value":"udl.png"},{"idObject":3,"type":"LOGO_LINK","value":"http://wwwen.uni.lu/"},{"idObject":7,"type":"SEARCH_DISTANCE","value":"10"},{"idObject":1,"type":"REQUEST_ACCOUNT_EMAIL","value":"your.email@domain.com"},{"idObject":8,"type":"SEARCH_RESULT_NUMBER","value":"100"},{"idObject":2,"type":"GOOGLE_ANALYTICS_IDENTIFIER","value":""},{"idObject":5,"type":"LOGO_TEXT","value":"University of Luxembourg"},{"idObject":56,"type":"X_FRAME_DOMAIN","value":"http://localhost:8080/"},{"idObject":131,"type":"BIG_FILE_STORAGE_DIR","value":"minerva-big/"},{"idObject":138,"type":"LENGEND_FILE_1","value":"resources/images/legend_a.png"},{"idObject":139,"type":"LENGEND_FILE_2","value":"resources/images/legend_b.png"},{"idObject":140,"type":"LENGEND_FILE_3","value":"resources/images/legend_c.png"},{"idObject":141,"type":"LENGEND_FILE_4","value":"resources/images/legend_d.png"},{"idObject":142,"type":"USER_MANUAL_FILE","value":"resources/other/user_guide.pdf"},{"idObject":205,"type":"MIN_COLOR_VAL","value":"FF0000"},{"idObject":206,"type":"MAX_COLOR_VAL","value":"fbff00"}],"overlayTypes":[{"name":"GENERIC"},{"name":"GENETIC_VARIANT"}]} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/user/login/login=&password=& b/frontend-js/testFiles/apiCalls/doLogin/POST_login=anonymous& similarity index 100% rename from frontend-js/testFiles/apiCalls/user/login/login=&password=& rename to frontend-js/testFiles/apiCalls/doLogin/POST_login=anonymous& diff --git a/frontend-js/testFiles/apiCalls/user/login/login=anonymous& b/frontend-js/testFiles/apiCalls/doLogin/POST_token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/user/login/login=anonymous& rename to frontend-js/testFiles/apiCalls/doLogin/POST_token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/genomics/getReferenceGenome/organism=1570291&token=MOCK_TOKEN_ID&type=UCSC&version=eboVir3& b/frontend-js/testFiles/apiCalls/genomics/taxonomies/1570291/types/UCSC/versions/eboVir3/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/genomics/getReferenceGenome/organism=1570291&token=MOCK_TOKEN_ID&type=UCSC&version=eboVir3& rename to frontend-js/testFiles/apiCalls/genomics/taxonomies/1570291/types/UCSC/versions/eboVir3/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayById/overlayId=90&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/overlay/getOverlayById/overlayId=90&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index a9b50caf04c15a0aff450272d62411ca15225cc9..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/overlay/getOverlayById/overlayId=90&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -{"modelId":15781,"name":"react","description":"","status":"OK","progress":"0.00","directory":"5e8ff9bf55ba3508199d22e984129be6/sample0.757974388121998714853","creator":"admin ","inputDataAvailable":"true","idObject":90} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=101&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=101&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index add8c44f962ac958939295544f2a7d1cc8981835..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=101&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"type":"ALIAS","overlayContent":{"value":1.0,"modelId":15781,"idObject":"329173"}}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=102&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=102&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 5814ef34f150c89697b9bf7b86adeff54831db41..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=102&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"type":"ALIAS","overlayContent":{"value":1.0,"modelId":100,"idObject":"1021"}}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayTypes/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/overlay/getOverlayTypes/token=MOCK_TOKEN_ID& deleted file mode 100644 index ad78fc8339659ed0731bb9b3896a5bdbad239f28..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/overlay/getOverlayTypes/token=MOCK_TOKEN_ID& +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "name": "GENERIC" - }, - { - "name": "GENETIC_VARIANT" - } -] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/updateOverlay/description=test%20desc2&name=test%20nam2&overlayId=17296&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/overlay/updateOverlay/description=test%20desc2&name=test%20nam2&overlayId=17296&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 84110294c8c0a0ad8a7aeb9ebc48f8c11fda10cb..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/overlay/updateOverlay/description=test%20desc2&name=test%20nam2&overlayId=17296&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1,3 +0,0 @@ -{ - "status": "OK" -} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=2.00,12.00&modelId=102&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=2.00,12.00&modelId=102&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 5b65788a70f9005afa290b59e8e39bd960613ca9..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=2.00,12.00&modelId=102&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"modelId":102,"id":329173,"type":"ALIAS"},{"modelId":102,"id":153511,"type":"REACTION"}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,39419.29&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,39419.29&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 189815b72bc0834d1f7750bf4b5a85a7cb4f3eda..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,39419.29&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"modelId":15781,"id":153515,"type":"REACTION"}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,40201.07&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,40201.07&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index 410f869e59ea4b0f4729f2cc68d0713359041200..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=26547.33,40201.07&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"modelId":15781,"id":329173,"type":"ALIAS"}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=30001&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=30001&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index ac811c267b5f5174bb9aefa2a9fd5ee809fd73aa..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=30001&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"formerSymbols":[],"references":[],"modelId":15781,"synonyms":[],"description":"","type":"Unknown","name":"s11","bounds":{"x":105.0,"y":203.5,"width":70.0,"height":25.0},"id":30001}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=1021&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=1021&projectId=sample&token=MOCK_TOKEN_ID& deleted file mode 100644 index c2af65e6ddc96433a9945f201a3ac31f799f8226..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=1021&projectId=sample&token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -[{"modelId":100,"bounds":{"x":683.0,"y":132.0,"width":70.0,"height":25.0},"id":1021}] \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/chemical/getChemicalsByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_images/overlays/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/chemical/getChemicalsByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_images/overlays/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getMetaData/projectId=complex_model_with_images&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_images/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getMetaData/projectId=complex_model_with_images&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_images/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345330,345331,345337&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345330,345331,345337&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345330,345331,345337&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345330,345331,345337&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345334&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345334&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345334&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345334&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345337&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345337&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=345337&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/models/all/bioEntities/elements/columns=id,bounds,modelId&id=345337&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=18083&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/18083/models/all/bioEntities/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=18083&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/18083/models/all/bioEntities/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayById/overlayId=18083&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/18083/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayById/overlayId=18083&projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/18083/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/comment/getCommentList/columns=&elementId=3001&elementType=ALIAS&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/comment/getCommentList/columns=&elementId=3001&elementType=ALIAS&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/overlays/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getMetaData/projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getMetaData/projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/complex_model_with_submaps/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/projects/sample.downloadSource/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample.downloadSource/token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..6489f980dd3a0e267379cc39ab9b1b2e9fe72f85 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample.downloadSource/token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"info":"dummy resposne"} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/miRna/getMiRnasByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/chemicals.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/miRna/getMiRnasByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/chemicals.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/chemical/getChemicalsByQuery/projectId=sample&query=rotenone&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/chemicals.search/query=rotenone&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/chemical/getChemicalsByQuery/projectId=sample&query=rotenone&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/chemicals.search/query=rotenone&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/bioEntities/elements/329173/POST_coordinates=2.00%2C12.00&pinned=false&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/bioEntities/elements/329173/POST_coordinates=2.00%2C12.00&pinned=false&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..abf1d949b09af93eb691795aa6b4a0c5af8981b5 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/bioEntities/elements/329173/POST_coordinates=2.00%2C12.00&pinned=false&token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"elementId":329173,"coord":{"x":735.0,"y":259.0},"removed":false,"modelId":15781,"icon":"icons/comment.png","id":4673,"title":"s23","type":"ALIAS","content":""} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/points/2.00,12.00/POST_pinned=false&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/points/2.00,12.00/POST_pinned=false&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..0304edbc07ecbda7ef2003114a21eef359dc1a86 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/15781/points/2.00,12.00/POST_pinned=false&token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"elementId":"(216.65,370.00)","coord":{"x":216.65,"y":370.0},"removed":false,"modelId":15781,"icon":"icons/comment.png","id":4671,"title":"Comment (coord: 2.00,12.00)","type":"POINT","content":""} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=complex_model_with_images&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/bioEntities/elements/3001/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=complex_model_with_images&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/bioEntities/elements/3001/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/comment/getCommentList/columns=&elementId=329158&elementType=ALIAS&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/bioEntities/elements/329158/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/comment/getCommentList/columns=&elementId=329158&elementType=ALIAS&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/bioEntities/elements/329158/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/comment/getCommentList/columns=id,elementId,modelId,type,icon,removed&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/columns=id,elementId,modelId,type,icon,removed&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/comment/getCommentList/columns=id,elementId,modelId,type,icon,removed&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/comments/models/all/columns=id,elementId,modelId,type,icon,removed&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/drug/getDrugsByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/drugs.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/drug/getDrugsByTarget/columns=name&projectId=sample&targetId=329170&targetType=ALIAS&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/drugs.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/drug/getDrugsByQuery/projectId=sample&query=NADH&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/drugs.search/query=NADH&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/drug/getDrugsByQuery/projectId=sample&query=NADH&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/drugs.search/query=NADH&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/drug/getDrugsByQuery/projectId=sample&query=aspirin&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/drugs.search/query=aspirin&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/drug/getDrugsByQuery/projectId=sample&query=aspirin&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/drugs.search/query=aspirin&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/miRnas.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=complex_model_with_submaps&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/miRnas.search/columns=name&target=ALIAS.329170&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/miRna/getMiRnasByQuery/projectId=sample&query=hsa-miR-125a-3p&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/miRnas.search/query=hsa-miR-125a-3p&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/miRna/getMiRnasByQuery/projectId=sample&query=hsa-miR-125a-3p&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/miRnas.search/query=hsa-miR-125a-3p&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadImage/handlerClass=lcsb.mapviewer.converter.graphics.PngImageGenerator&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadImage/handlerClass=lcsb.mapviewer.converter.graphics.PngImageGenerator&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..6489f980dd3a0e267379cc39ab9b1b2e9fe72f85 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadImage/handlerClass=lcsb.mapviewer.converter.graphics.PngImageGenerator&token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"info":"dummy resposne"} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadModel/handlerClass=lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadModel/handlerClass=lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..6489f980dd3a0e267379cc39ab9b1b2e9fe72f85 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/models/15781.downloadModel/handlerClass=lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser&token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"info":"dummy resposne"} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=184.79,365.76&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=184.79,365.76&count=1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=184.79,365.76&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=184.79,365.76&count=1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=2.00,12.00&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=2.00,12.00&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=2.00,12.00&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=2.00,12.00&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=207.73,479.18&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=207.73,479.18&count=1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=207.73,479.18&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=207.73,479.18&count=1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=316.05,253.61&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=316.05,253.61&count=1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=316.05,253.61&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=316.05,253.61&count=1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=457.51,356.84&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=457.51,356.84&count=1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=457.51,356.84&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=457.51,356.84&count=1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=553.10,479.18&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=553.10,479.18&count=1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getClosestElementsByCoordinates/coordinates=553.10,479.18&count=1&modelId=15781&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/15781/bioEntities.search/coordinates=553.10,479.18&count=1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElementsByQuery/perfectMatch=false&projectId=sample&query=s1&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities.search/perfectMatch=false&query=s1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElementsByQuery/perfectMatch=false&projectId=sample&query=s1&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities.search/perfectMatch=false&query=s1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElementsByQuery/projectId=sample&query=s1&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities.search/query=s1&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElementsByQuery/projectId=sample&query=s1&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities.search/query=s1&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329159&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329159&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329159&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329159&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329163&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329163&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329163&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329163&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329167&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329167&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329167&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329167&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329168,329173&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329168,329173&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329168,329173&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329168,329173&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329170&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329170&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329170&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329170&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329171&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329171&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329171&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329171&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329173&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329173&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=329173&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&id=329173&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=id,bounds,modelId&id=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/columns=id,bounds,modelId&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329156,329162,329174,329180&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329156,329162,329174,329180&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329156,329162,329174,329180&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329156,329162,329174,329180&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158,329159,329169,329173,329175,329177&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158,329159,329169,329173,329175,329177&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158,329159,329169,329173,329175,329177&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158,329159,329169,329173,329175,329177&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158,329165,329172&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158,329165,329172&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329158,329165,329172&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329158,329165,329172&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329159&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329159&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329159&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329159&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329166,329171&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329166,329171&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329166,329171&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329166,329171&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329167,329173,329179&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329167,329173,329179&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329167,329173,329179&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329167,329173,329179&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329167,329179&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329167,329179&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329167,329179&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329167,329179&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168,329173&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168,329173&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168,329173&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168,329173&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168,329177&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168,329177&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329168,329177&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329168,329177&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329171&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329171&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329171&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329171&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329173&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329173&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329173&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329173&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329177&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329177&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getElements/columns=&id=329177&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/elements/id=329177&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153508&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153508&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153508&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153508&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153510&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153510&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153510&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153510&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153511&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153511&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153511&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153511&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153515&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153515&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153515&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153515&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153519&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153519&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153519&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153519&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153521&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153521&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=153521&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/id=153521&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=&participantId=329167&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=&participantId=329167&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/participantId=329167&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=&participantId=&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getReactions/columns=&id=&participantId=&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/reactions/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getSuggestedQueryList/projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/suggestedQueryList/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getSuggestedQueryList/projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/bioEntities/suggestedQueryList/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getPublications/length=10&projectId=sample&start=0&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/models/all/publications/length=10&start=0&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getPublications/length=10&projectId=sample&start=0&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/models/all/publications/length=10&start=0&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296.downloadSource/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296.downloadSource/token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..6489f980dd3a0e267379cc39ab9b1b2e9fe72f85 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296.downloadSource/token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"info":"dummy resposne"} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296/DELETE_token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296/DELETE_token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296/DELETE_token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/overlay/removeOverlay/overlayId=17296&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/17296/PATCH_overlay.description=test desc2&overlay.name=test nam2&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/removeOverlay/overlayId=17296&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/17296/PATCH_overlay.description=test desc2&overlay.name=test nam2&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElement/elementId=329163&elementType=ALIAS&modelId=15781&overlayId=18076&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/18076/models/15781/bioEntities/elements/329163/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayElement/elementId=329163&elementType=ALIAS&modelId=15781&overlayId=18076&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/18076/models/15781/bioEntities/elements/329163/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElement/elementId=329163&elementType=ALIAS&modelId=15781&overlayId=18077&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/18077/models/15781/bioEntities/elements/329163/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayElement/elementId=329163&elementType=ALIAS&modelId=15781&overlayId=18077&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/18077/models/15781/bioEntities/elements/329163/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=18077&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/18077/models/all/bioEntities/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayElements/overlayId=18077&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/18077/models/all/bioEntities/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/addOverlay/content=name%20color%0ACAPN1%20%2300FF00%0APARK7%20%23AC0000&description=test%20desc&filename=test.txt&name=test%20nam&projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_content=name%20color%0ACAPN1%20%2300FF00%0APARK7%20%23AC0000&description=test%20desc&filename=test.txt&name=test%20nam&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/addOverlay/content=name%20color%0ACAPN1%20%2300FF00%0APARK7%20%23AC0000&description=test%20desc&filename=test.txt&name=test%20nam&projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_content=name%20color%0ACAPN1%20%2300FF00%0APARK7%20%23AC0000&description=test%20desc&filename=test.txt&name=test%20nam&token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/overlay/getOverlayList/projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/project/getMetaData/projectId=sample&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/project/getMetaData/projectId=sample&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/token=MOCK_TOKEN_ID& diff --git a/frontend-js/testFiles/apiCalls/user/tokenStatus/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/user/tokenStatus/token=MOCK_TOKEN_ID& deleted file mode 100644 index 3ea855693d7bc2b6b61245cb5da138bf4ecf3337..0000000000000000000000000000000000000000 --- a/frontend-js/testFiles/apiCalls/user/tokenStatus/token=MOCK_TOKEN_ID& +++ /dev/null @@ -1 +0,0 @@ -{"id":"MOCK_TOKEN_ID","expires":{"year":3017,"month":0,"dayOfMonth":30,"hourOfDay":18,"minute":34,"second":13}} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/user/getUser/token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/users/anonymous/token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/user/getUser/token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/users/anonymous/token=MOCK_TOKEN_ID& diff --git a/pom.xml b/pom.xml index 7e0e056d5673bde6dca10ac4b7aa1e99afb5718e..c4ae7d49e1981914751eb1164fe8e0733c5f00b6 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,9 @@ <jersey.version>1.18.1</jersey.version> <rs-jax.version>1.1.1</rs-jax.version> + <jackson.version>2.8.8</jackson.version> + + <log4j.version>1.2.17</log4j.version> <apache.commons-lang3.version>3.1</apache.commons-lang3.version> diff --git a/rest-api/.classpath b/rest-api/.classpath index f2b9c43c7c685c67e2e11da797cf4c21f6413792..3783d3d93c885fcd1b40df6fe49f64d056876503 100644 --- a/rest-api/.classpath +++ b/rest-api/.classpath @@ -1,29 +1,37 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" output="target/classes" path="src/main/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" path="src/main/resources"/> - <classpathentry kind="src" path="src/test/resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - <attribute name="org.eclipse.jst.component.nondependency" value=""/> - </attributes> - </classpathentry> - <classpathentry kind="output" path="target/classes"/> -</classpath> +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + <attribute name="org.eclipse.jst.component.nondependency" value=""/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/rest-api/.settings/org.eclipse.core.resources.prefs b/rest-api/.settings/org.eclipse.core.resources.prefs index 4c28b1a898a0f0bc507b93f8f5393d172709fe73..04cfa2c1a8566d64dd12fcf7a8e895fe02e1856f 100644 --- a/rest-api/.settings/org.eclipse.core.resources.prefs +++ b/rest-api/.settings/org.eclipse.core.resources.prefs @@ -1,4 +1,6 @@ eclipse.preferences.version=1 encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 encoding/<project>=UTF-8 diff --git a/rest-api/pom.xml b/rest-api/pom.xml index cb185247b69e544ac04cede7b3a1e1357321cf22..43e369a82a68de23354175284a8441d1333373b8 100644 --- a/rest-api/pom.xml +++ b/rest-api/pom.xml @@ -48,6 +48,25 @@ <artifactId>spring-faces</artifactId> <version>${springframework.webflow.version}</version> </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <version>${jackson.version}</version> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>${jackson.version}</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>${servlet-api.version}</version> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.mockito</groupId> diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java index d7f6e3c8fefb0e3c34f2e194d419d3534d431e8b..33c31dfccce0953bd8402725cdfc1e7663224ab6 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java @@ -1,6 +1,6 @@ package lcsb.mapviewer.api; -import java.util.HashMap; +import java.io.IOException; import java.util.Map; import org.apache.log4j.Logger; @@ -10,22 +10,40 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + public abstract class BaseController { - Logger logger = Logger.getLogger(BaseController.class); + private Logger logger = Logger.getLogger(BaseController.class); + + private ObjectMapper mapper = new ObjectMapper(); @ExceptionHandler({ Exception.class }) public ResponseEntity<Object> handleException(Exception e, WebRequest request) { - logger.error(e, e); - if (e instanceof SecurityException) { + if (e instanceof lcsb.mapviewer.services.SecurityException) { return new ResponseEntity<Object>("{\"error\" : \"Access denied.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.FORBIDDEN); + } else if (e instanceof ObjectNotFoundException) { + return new ResponseEntity<Object>("{\"error\" : \"Object not found.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.NOT_FOUND); } else if (e instanceof QueryException) { return new ResponseEntity<Object>( "{\"error\" : \"Query server error.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.BAD_REQUEST); } else { + logger.error(e, e); return new ResponseEntity<Object>( "{\"error\" : \"Internal server error.\",\"reason\":\"" + e.getMessage() + "\"}", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); } } + protected Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException { + logger.debug("Parse body: " + body); + ObjectNode result = mapper.readValue(body, ObjectNode.class); + return mapper.convertValue(result, Map.class); + } + + protected Map<String, Object> getData(Map<String, Object> node, String objectName) { + return (Map<String, Object>) node.get(objectName); + } } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java index d863d798008b0b1b1fc70fdcaf4b9e053b57f3b8..272e3998a2bc4311e8abcf4df0da70d1019b39f7 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java @@ -1,12 +1,100 @@ package lcsb.mapviewer.api; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.common.exception.InvalidStateException; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; + +@Transactional(value = "txManager") public abstract class BaseRestImpl { + @Autowired + private IModelService modelService; + @Autowired + private IUserService userService; + protected Map<String, Object> okStatus() { Map<String, Object> result = new HashMap<>(); - result.put("status", "OK"); return result; } + + protected Map<String, Object> createMinifiedSearchResult(Object object) { + Map<String, Object> result = new HashMap<>(); + if (object instanceof Element) { + result.put("type", ElementIdentifierType.ALIAS); + Element element = (Element) object; + result.put("id", element.getId()); + result.put("modelId", element.getModel().getId()); + } else if (object instanceof Reaction) { + result.put("type", ElementIdentifierType.REACTION); + Reaction element = (Reaction) object; + result.put("id", element.getId()); + result.put("modelId", element.getModel().getId()); + + } else { + throw new InvalidStateException("Unknown type of result: " + object.getClass()); + } + return result; + }; + + protected List<Model> getModels(String projectId, String modelId, String token) throws SecurityException { + Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); + List<Model> models = new ArrayList<>(); + + if (!modelId.equals("*")) { + for (String str : modelId.split(",")) { + models.add(model.getSubmodelById(Integer.valueOf(str))); + } + } else { + models.addAll(model.getSubmodels()); + models.add(model); + } + return models; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/ObjectNotFoundException.java b/rest-api/src/main/java/lcsb/mapviewer/api/ObjectNotFoundException.java new file mode 100644 index 0000000000000000000000000000000000000000..907d839df8494dcb46b12c4bba327ee996c79d84 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/ObjectNotFoundException.java @@ -0,0 +1,13 @@ +package lcsb.mapviewer.api; + +public class ObjectNotFoundException extends QueryException { + + public ObjectNotFoundException(String message) { + super(message); + } + + public ObjectNotFoundException(String message, Exception reason) { + super(message, reason); + } + +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalController.java b/rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalController.java deleted file mode 100644 index 980529bdd745e4f4e7f818e7e967c51ab59791e1..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalController.java +++ /dev/null @@ -1,39 +0,0 @@ -package lcsb.mapviewer.api.chemical; - -import java.awt.geom.Point2D; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.services.SecurityException; - -@RestController -@RequestMapping("/chemical") -public class ChemicalController extends BaseController { - - @Autowired - private ChemicalRestImpl chemicalController; - - @RequestMapping(value = "/getChemicalsByQuery", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getChemicalsByQuery(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "query") String query) - throws SecurityException, QueryException { - return chemicalController.getChemicalsByQuery(token, projectId, columns, query); - } - - @RequestMapping(value = "/getChemicalsByTarget", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getChemicalsByTarget(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "targetType", defaultValue = "ALIAS") String targetType, @RequestParam(value = "targetId", defaultValue = "") String targetId, - @RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException { - return chemicalController.getChemicalsByTarget(token, projectId, targetType, targetId, columns); - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java b/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java deleted file mode 100644 index 6d2a17042b7a00b25155bcf7c67fd92d58046705..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentController.java +++ /dev/null @@ -1,73 +0,0 @@ -package lcsb.mapviewer.api.comment; - -import java.awt.geom.Point2D; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.services.SecurityException; - -@RestController -@RequestMapping("/comment") -public class CommentController extends BaseController { - - @Autowired - private CommentRestImpl commentController; - - @RequestMapping(value = "/getCommentList", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getOverlayList(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "elementId", defaultValue = "") String elementId, - @RequestParam(value = "elementType", defaultValue = "") String elementType, @RequestParam(value = "removed", defaultValue = "") String removed) - throws SecurityException, QueryException { - return commentController.getCommentList(token, projectId, columns, elementId, elementType, removed); - } - - @RequestMapping(value = "/addComment", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> addComment(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "elementType", defaultValue = "POINT") String elementType, @RequestParam(value = "elementId", defaultValue = "") String elementId, - @RequestParam(value = "name") String name, @RequestParam(value = "email") String email, @RequestParam(value = "content") String content, - @RequestParam(value = "pinned", defaultValue = "true") String pinned, @RequestParam(value = "coordinates") String coordinates, - @RequestParam(value = "modelId") String modelId) throws SecurityException, QueryException { - String[] tmp = coordinates.split(","); - if (tmp.length != 2) { - throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'"); - } - Double x = null; - Double y = null; - try { - x = Double.valueOf(tmp[0]); - y = Double.valueOf(tmp[1]); - } catch (NumberFormatException e) { - throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e); - } - Point2D pointCoordinates = new Point2D.Double(x, y); - return commentController - .addComment(token, projectId, elementType, elementId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates, modelId); - } - - /** - * @return the overlayController - * @see #commentController - */ - public CommentRestImpl getOverlayController() { - return commentController; - } - - /** - * @param overlayController - * the overlayController to set - * @see #commentController - */ - public void setOverlayController(CommentRestImpl overlayController) { - this.commentController = overlayController; - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java index 2a12fe063d0e0ff08e8f722fab2fabc4eb73bc2b..4b582a14a8a4ff3157205ca552e04db432f3775a 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java @@ -1,41 +1,32 @@ package lcsb.mapviewer.api.configuration; -import java.util.List; +import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.services.SecurityException; -import lcsb.mapviewer.services.view.ConfigurationView; @RestController -@RequestMapping("/configuration") public class ConfigurationController extends BaseController { @Autowired private ConfigurationRestImpl configurationController; - @RequestMapping(value = "/getAllValues", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<ConfigurationView> getAllValues(@RequestParam(value = "token") String token) - throws SecurityException { - return configurationController.getAllValues(token); - } - - @RequestMapping(value = "/getImageFormats", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getImageFormats(@RequestParam(value = "token") String token) - throws SecurityException { - return configurationController.getImageFormats(token); - } - - @RequestMapping(value = "/getModelFormats", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getModelFormats(@RequestParam(value = "token") String token) - throws SecurityException { - return configurationController.getModelFormats(token); + @RequestMapping(value = "/configuration/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getOverlayTypes(@CookieValue(value = Configuration.AUTH_TOKEN) String token) throws SecurityException { + Map<String, Object> result = new HashMap<>(); + result.put("options", configurationController.getAllValues(token)); + result.put("imageFormats", configurationController.getImageFormats(token)); + result.put("modelFormats", configurationController.getModelFormats(token)); + result.put("overlayTypes", configurationController.getOverlayTypes(token)); + return result; } /** @@ -47,7 +38,8 @@ public class ConfigurationController extends BaseController { } /** - * @param configurationController the configurationController to set + * @param configurationController + * the configurationController to set * @see #configurationController */ public void setConfigurationController(ConfigurationRestImpl configurationController) { diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java index 5d7da5242a67da3c5c7d6722fff0b60803be7e78..7c32c550344ddca5b6fec891be72da0dc0d905f9 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java @@ -18,6 +18,7 @@ import lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.interfaces.IConfigurationService; import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.utils.data.ColorSchemaType; import lcsb.mapviewer.services.view.ConfigurationView; @Transactional(value = "txManager") @@ -29,7 +30,8 @@ public class ConfigurationRestImpl { @Autowired private IConfigurationService configurationService; - public List<ConfigurationView> getAllValues(@RequestParam(value = "token") String token) throws SecurityException { + public List<ConfigurationView> getAllValues(String token) throws SecurityException { + userService.getToken(token); return configurationService.getAllValues(); } @@ -67,7 +69,8 @@ public class ConfigurationRestImpl { this.configurationService = configurationService; } - public List<Map<String, Object>> getImageFormats(String token) { + public List<Map<String, Object>> getImageFormats(String token) throws SecurityException { + userService.getToken(token); List<Map<String, Object>> result = new ArrayList<>(); List<Pair<String, Class<? extends AbstractImageGenerator>>> imageGenerators = new ImageGenerators().getAvailableImageGenerators(); @@ -81,7 +84,8 @@ public class ConfigurationRestImpl { return result; } - public List<Map<String, Object>> getModelFormats(String token) { + public List<Map<String, Object>> getModelFormats(String token) throws SecurityException { + userService.getToken(token); List<IConverter> converters = new ArrayList<>(); converters.add(new CellDesignerXmlParser()); converters.add(new SbgnmlXmlConverter()); @@ -97,4 +101,15 @@ public class ConfigurationRestImpl { return result; } + public List<Map<String, Object>> getOverlayTypes(String token) throws SecurityException { + userService.getToken(token); + List<Map<String, Object>> result = new ArrayList<>(); + for (ColorSchemaType type : ColorSchemaType.values()) { + Map<String, Object> map = new HashMap<>(); + map.put("name", type.name()); + result.add(map); + } + return result; + } + } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java b/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java deleted file mode 100644 index 92b2cb39564d74a47c4d54e088647173bb717f8b..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserController.java +++ /dev/null @@ -1,98 +0,0 @@ -package lcsb.mapviewer.api.controller; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.common.Configuration; -import lcsb.mapviewer.services.SecurityException; -import lcsb.mapviewer.services.interfaces.IUserService; -import lcsb.mapviewer.services.view.AuthenticationToken; - -@RestController -@RequestMapping("/user") -public class UserController extends BaseController { - Logger logger = Logger.getLogger(UserController.class); - - @Autowired - private IUserService userService; - - @Autowired - private UserRestImpl userRest; - - @RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> login(@RequestParam(value = "login", defaultValue = Configuration.ANONYMOUS_LOGIN) String login, - @RequestParam(value = "password", required = false) String password) { - AuthenticationToken token = userService.login(login, password); - Map<String, Object> result = new HashMap<>(); - if (token == null) { - result.put("error", "Invalid credentials"); - } else { - result.put("id", token.getId()); - result.put("expires", token.getExpires()); - } - return result; - } - - @RequestMapping(value = "/tokenStatus", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public AuthenticationToken tokenSatus(@RequestParam(value = "token", required = false) String token) throws SecurityException { - return userService.getToken(token); - } - - @RequestMapping(value = "/getUser", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> getUser(@RequestParam(value = "token", required = false) String token, - @RequestParam(value = "userId", defaultValue = "") String userId, @RequestParam(value = "columns", defaultValue = "") String columns) - throws SecurityException { - return userRest.getUser(token, userId, columns); - } - - @RequestMapping(value = "/logout", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, String> logout(@RequestParam(value = "token", required = false) String token) throws SecurityException { - userService.logout(token); - Map<String, String> response = new HashMap<>(); - response.put("status", "OK"); - return response; - } - - /** - * @return the userService - * @see #userService - */ - public IUserService getUserService() { - return userService; - } - - /** - * @param userService - * the userService to set - * @see #userService - */ - public void setUserService(IUserService userService) { - this.userService = userService; - } - - /** - * @return the userRest - * @see #userRest - */ - public UserRestImpl getUserRest() { - return userRest; - } - - /** - * @param userRest - * the userRest to set - * @see #userRest - */ - public void setUserRest(UserRestImpl userRest) { - this.userRest = userRest; - } -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugController.java b/rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugController.java deleted file mode 100644 index 4d109d08593c5ac48c1bdecb8d1b9682ded7eb79..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugController.java +++ /dev/null @@ -1,39 +0,0 @@ -package lcsb.mapviewer.api.drug; - -import java.awt.geom.Point2D; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.services.SecurityException; - -@RestController -@RequestMapping("/drug") -public class DrugController extends BaseController { - - @Autowired - private DrugRestImpl drugController; - - @RequestMapping(value = "/getDrugsByQuery", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getDrugsByQuery(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "query") String query) - throws SecurityException, QueryException { - return drugController.getDrugsByQuery(token, projectId, columns, query); - } - - @RequestMapping(value = "/getDrugsByTarget", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getDrugsByTarget(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "targetType", defaultValue = "ALIAS") String targetType, @RequestParam(value = "targetId", defaultValue = "") String targetId, - @RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException { - return drugController.getDrugsByTarget(token, projectId, targetType, targetId, columns); - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeController.java b/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeController.java index 3176a006de6c8f80ce228f7b6b58ed6ce054f7cf..e60c7ba05c63e71c3e9e50e48828022ad90dbb27 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeController.java @@ -2,6 +2,8 @@ package lcsb.mapviewer.api.genomics; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -9,19 +11,24 @@ import org.springframework.web.bind.annotation.RestController; import lcsb.mapviewer.api.BaseController; import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.view.ReferenceGenomeView; @RestController -@RequestMapping("/genomics") public class ReferenceGenomeController extends BaseController { @Autowired private ReferenceGenomeRestImpl referenceGenomeController; - @RequestMapping(value = "/getReferenceGenome", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ReferenceGenomeView getDrugsByQuery(@RequestParam(value = "token") String token, @RequestParam(value = "organism") String organism, - @RequestParam(value = "type") String type, @RequestParam(value = "version", defaultValue = "") String version) throws SecurityException, QueryException { + @RequestMapping(value = "/genomics/taxonomies/{organismId}/genomeTypes/{type}/versions/{version}/", method = { RequestMethod.GET, RequestMethod.POST }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public ReferenceGenomeView getDrugsByQuery(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "organismId") String organism, // + @PathVariable(value = "type") String type, // + @PathVariable(value = "version") String version// + ) throws SecurityException, QueryException { return referenceGenomeController.getReferenceGenome(token, organism, type, version); } } \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeRestImpl.java index 0c9f2d05b6fe575c51e6b88b316eda6e60a32154..9f8555638b7916d51c90453d4ae3f2718e3428e7 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/genomics/ReferenceGenomeRestImpl.java @@ -40,6 +40,7 @@ public class ReferenceGenomeRestImpl { ReferenceGenomeView result = null; try { ReferenceGenomeType genomeType = ReferenceGenomeType.valueOf(type); + version = version.replaceAll("\\*", ""); result = referenceGenomeService.getReferenceGenomeViewByParams(organism, genomeType, version, authenticationToken); if (result == null) { throw new QueryException("Cannot find requested reference genome"); diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java b/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java deleted file mode 100644 index 46ec8084bfca5e0e7b10a0e5fe8fc6a7b72a189f..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java +++ /dev/null @@ -1,38 +0,0 @@ -package lcsb.mapviewer.api.mirna; - -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.services.SecurityException; - -@RestController -@RequestMapping("/miRna") -public class MiRnaController extends BaseController { - - @Autowired - private MiRnaRestImpl miRnaController; - - @RequestMapping(value = "/getMiRnasByQuery", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getMiRnasByQuery(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "query") String query) - throws SecurityException, QueryException { - return miRnaController.getMiRnasByQuery(token, projectId, columns, query); - } - - @RequestMapping(value = "/getMiRnasByTarget", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getMiRnasByTarget(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "targetType", defaultValue = "ALIAS") String targetType, @RequestParam(value = "targetId", defaultValue = "") String targetId, - @RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException { - return miRnaController.getMiRnasByTarget(token, projectId, targetType, targetId, columns); - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayController.java b/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayController.java deleted file mode 100644 index ddfea072ef12f2818d59d0436387f5d22f1b7a52..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayController.java +++ /dev/null @@ -1,117 +0,0 @@ -package lcsb.mapviewer.api.overlay; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.model.cache.FileEntry; -import lcsb.mapviewer.services.SecurityException; -import lcsb.mapviewer.services.utils.data.ColorSchemaType; -import lcsb.mapviewer.services.view.LayoutView; - -@RestController -@RequestMapping("/overlay") -public class OverlayController extends BaseController { - - @Autowired - private OverlayRestImpl overlayController; - - @RequestMapping(value = "/getOverlayList", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<LayoutView> getOverlayList(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId) - throws SecurityException, QueryException { - return overlayController.getOverlayList(token, projectId); - } - - @RequestMapping(value = "/getOverlayTypes", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getOverlayTypes(@RequestParam(value = "token") String token) throws SecurityException, QueryException { - return overlayController.getOverlayTypes(token); - } - - @RequestMapping(value = "/getOverlayById", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public LayoutView getOverlayById(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "overlayId") String overlayId) throws SecurityException, QueryException { - return overlayController.getOverlayById(token, projectId, overlayId); - } - - @RequestMapping(value = "/updateOverlay", method = { RequestMethod.GET, RequestMethod.PUT, RequestMethod.POST }, - produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> updateOverlay(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "overlayId") String overlayId, @RequestParam(value = "name") String name, @RequestParam(value = "description") String description) - throws SecurityException, QueryException { - return overlayController.updateOverlay(token, projectId, overlayId, name, description); - } - - @RequestMapping(value = "/addOverlay", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> addOverlay(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "name") String name, @RequestParam(value = "description") String description, @RequestParam(value = "content") String content, - @RequestParam(value = "filename") String filename, @RequestParam(value = "type", defaultValue = "") String type) - throws SecurityException, QueryException, IOException { - return overlayController.addOverlay(token, projectId, name, description, content, filename, type); - } - - @RequestMapping(value = "/removeOverlay", method = { RequestMethod.GET, RequestMethod.DELETE, RequestMethod.POST }, - produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> removeOverlay(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "overlayId") String overlayId) throws SecurityException, QueryException, IOException { - return overlayController.removeOverlay(token, projectId, overlayId); - } - - @RequestMapping(value = "/getOverlaySource", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getOverlaySource(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "overlayId") String overlayId) throws SecurityException, QueryException { - - FileEntry file = overlayController.getOverlaySource(token, projectId, overlayId); - MediaType type = MediaType.TEXT_PLAIN; - if (file.getOriginalFileName().endsWith("xml")) { - type = MediaType.APPLICATION_XML; - } - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - @RequestMapping(value = "/getOverlayElements", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getOverlayElements(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "overlayId") String overlayId, @RequestParam(value = "columns", defaultValue = "") String columns) - throws SecurityException, QueryException { - return overlayController.getOverlayElements(token, projectId, Integer.valueOf(overlayId), columns); - } - - @RequestMapping(value = "/getOverlayElement", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> getFullElement(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "modelId") String modelId, @RequestParam(value = "overlayId") String overlayId, - @RequestParam(value = "elementId") String elementId, @RequestParam(value = "elementType") String elementType, - @RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException { - return overlayController - .getOverlayElement(token, projectId, Integer.valueOf(modelId), Integer.valueOf(overlayId), Integer.valueOf(elementId), elementType, columns); - } - - /** - * @return the overlayController - * @see #overlayController - */ - public OverlayRestImpl getOverlayController() { - return overlayController; - } - - /** - * @param overlayController - * the overlayController to set - * @see #overlayController - */ - public void setOverlayController(OverlayRestImpl overlayController) { - this.overlayController = overlayController; - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java deleted file mode 100644 index babade2eb7110f5e39254b3b6f7631a7b011213e..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectController.java +++ /dev/null @@ -1,137 +0,0 @@ -package lcsb.mapviewer.api.project; - -import java.awt.geom.Point2D; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import lcsb.mapviewer.api.BaseController; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.commands.CommandExecutionException; -import lcsb.mapviewer.converter.ConverterException; -import lcsb.mapviewer.model.cache.FileEntry; -import lcsb.mapviewer.model.map.InconsistentModelException; -import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; -import lcsb.mapviewer.services.SecurityException; - -@RestController -@RequestMapping("/project") -public class ProjectController extends BaseController { - @Autowired - private ProjectRestImpl projectController; - - @RequestMapping(value = "/getMetaData", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ProjectMetaData getMetaData(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token) - throws SecurityException { - return projectController.getMetaData(projectId, token); - } - - @RequestMapping(value = "/getSuggestedQueryList", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public String[] getSuggestedQueryList(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token) - throws SecurityException { - return projectController.getSuggestedQueryList(projectId, token); - } - - @RequestMapping(value = "/getElements", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getElements(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "id", defaultValue = "") String id, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "token") String token) throws SecurityException { - return projectController.getElements(projectId, id, columns, token); - } - - @RequestMapping(value = "/getReactions", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getReactions(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "id", defaultValue = "") String id, - @RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "token") String token, - @RequestParam(value = "participantId", defaultValue = "") String participantId) throws SecurityException { - return projectController.getReactions(projectId, id, columns, token, participantId); - } - - @RequestMapping(value = "/getClosestElementsByCoordinates", method = { RequestMethod.GET, RequestMethod.POST }, - produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getClosestElementsByCoordinates(@RequestParam(value = "projectId") String projectId, - @RequestParam(value = "modelId") String modelId, @RequestParam(value = "token") String token, @RequestParam(value = "coordinates") String coordinates, - @RequestParam(value = "count", defaultValue = "5") String count) throws QueryException, SecurityException { - String[] tmp = coordinates.split(","); - if (tmp.length != 2) { - throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'"); - } - Double x = null; - Double y = null; - try { - x = Double.valueOf(tmp[0]); - y = Double.valueOf(tmp[1]); - } catch (NumberFormatException e) { - throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e); - } - Point2D pointCoordinates = new Point2D.Double(x, y); - return projectController.getClosestElementsByCoordinates(projectId, modelId, token, pointCoordinates, Integer.valueOf(count)); - } - - @RequestMapping(value = "/getElementsByQuery", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public List<Map<String, Object>> getElementsByQuery(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token, - @RequestParam(value = "query") String query, @RequestParam(value = "maxElements", defaultValue = "100") Integer maxElements, - @RequestParam(value = "perfectMatch", defaultValue = "false") String perfectMatch) throws QueryException, SecurityException { - return projectController.getElementsByQuery(projectId, token, query, maxElements, perfectMatch); - } - - @RequestMapping(value = "/getPublications", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map<String, Object> getPublications(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token, - @RequestParam(value = "start", defaultValue = "0") String start, @RequestParam(value = "length", defaultValue = "10") Integer length) - throws QueryException, SecurityException { - return projectController.getPublications(projectId, token, start, length); - } - - @RequestMapping(value = "/getProjectSource", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getProjectSource(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId) - throws SecurityException, QueryException { - - FileEntry file = projectController.getSource(token, projectId); - MediaType type = MediaType.TEXT_PLAIN; - if (file.getOriginalFileName().endsWith("xml")) { - type = MediaType.APPLICATION_XML; - } else if (file.getOriginalFileName().endsWith("zip")) { - type = MediaType.APPLICATION_OCTET_STREAM; - } - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - @RequestMapping(value = "/getModelAsImage", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getModelAsImage(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "modelId") String modelId, @RequestParam(value = "handlerClass") String handlerClass, - @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, - @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, - @RequestParam(value = "polygonString", defaultValue = "") String polygonString) - throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException { - - FileEntry file = projectController.getModelAsImage(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); - MediaType type = MediaType.APPLICATION_OCTET_STREAM; - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - - @RequestMapping(value = "/getModelAsModelFile", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity<byte[]> getModelAsModelFile(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId, - @RequestParam(value = "modelId") String modelId, @RequestParam(value = "handlerClass") String handlerClass, - @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, - @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, - @RequestParam(value = "polygonString") String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, - CommandExecutionException, ConverterException, InconsistentModelException { - - FileEntry file = projectController.getModelAsModelFile(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); - MediaType type = MediaType.APPLICATION_OCTET_STREAM; - return ResponseEntity - .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) - .body(file.getFileContent()); - } - -} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java deleted file mode 100644 index 2e820ac49333302596ff944b225e2e4f51a0ecfb..0000000000000000000000000000000000000000 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectRestImpl.java +++ /dev/null @@ -1,802 +0,0 @@ -package lcsb.mapviewer.api.project; - -import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.RequestParam; - -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.api.QueryException; -import lcsb.mapviewer.commands.ClearColorModelCommand; -import lcsb.mapviewer.commands.ColorExtractor; -import lcsb.mapviewer.commands.ColorModelCommand; -import lcsb.mapviewer.commands.CommandExecutionException; -import lcsb.mapviewer.commands.CopyCommand; -import lcsb.mapviewer.commands.SubModelCommand; -import lcsb.mapviewer.common.Configuration; -import lcsb.mapviewer.common.exception.InvalidStateException; -import lcsb.mapviewer.converter.ConverterException; -import lcsb.mapviewer.converter.IConverter; -import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; -import lcsb.mapviewer.converter.graphics.ImageGenerators; -import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; -import lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter; -import lcsb.mapviewer.model.Project; -import lcsb.mapviewer.model.cache.FileEntry; -import lcsb.mapviewer.model.cache.UploadedFileEntry; -import lcsb.mapviewer.model.map.AnnotatedObject; -import lcsb.mapviewer.model.map.InconsistentModelException; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.OverviewImage; -import lcsb.mapviewer.model.map.OverviewImageLink; -import lcsb.mapviewer.model.map.OverviewLink; -import lcsb.mapviewer.model.map.layout.ColorSchema; -import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; -import lcsb.mapviewer.model.map.layout.Layout; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.model.ModelData; -import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; -import lcsb.mapviewer.model.map.reaction.Modifier; -import lcsb.mapviewer.model.map.reaction.Product; -import lcsb.mapviewer.model.map.reaction.Reactant; -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.model.map.species.Element; -import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.model.user.User; -import lcsb.mapviewer.services.SecurityException; -import lcsb.mapviewer.services.UserAccessException; -import lcsb.mapviewer.services.interfaces.ILayoutService; -import lcsb.mapviewer.services.interfaces.IModelService; -import lcsb.mapviewer.services.interfaces.IProjectService; -import lcsb.mapviewer.services.interfaces.ISearchService; -import lcsb.mapviewer.services.interfaces.IUserService; -import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; -import lcsb.mapviewer.services.search.data.LightReactionView; -import lcsb.mapviewer.services.utils.ColorSchemaReader; -import lcsb.mapviewer.services.utils.data.BuildInLayout; -import lcsb.mapviewer.services.utils.gmap.CoordinationConverter; -import lcsb.mapviewer.services.view.AnnotationViewFactory; -import lcsb.mapviewer.services.view.AuthenticationToken; -import lcsb.mapviewer.services.view.OverviewImageViewFactory; - -@Transactional(value = "txManager") -public class ProjectRestImpl { - - /** - * Constant defining size of the array returned by - * {@link PathIterator#currentSegment(double[])} method. More nformation can - * be found <a href= - * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])" - * >here</a> - */ - private static final int PATH_ITERATOR_SEGMENT_SIZE = 6; - - Logger logger = Logger.getLogger(ProjectRestImpl.class); - - @Autowired - private IUserService userService; - - @Autowired - private IProjectService projectService; - - @Autowired - private IModelService modelService; - - @Autowired - private ISearchService searchService; - - @Autowired - AnnotationViewFactory annotationViewFactory; - - @Autowired - private PubmedParser pubmedParser; - - @Autowired - private ILayoutService layoutService; - - @Autowired - private OverviewImageViewFactory factory; - - public ProjectMetaData getMetaData(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "token") String token) - throws SecurityException { - AuthenticationToken authenticationToken = userService.getToken(token); - Project project = projectService.getProjectByProjectId(projectId, authenticationToken); - ProjectMetaData result = createData(project, authenticationToken); - if (project.getOrganism() != null) { - result.setOrganism(annotationViewFactory.create(project.getOrganism())); - } - if (project.getDisease() != null) { - result.setDisease(annotationViewFactory.create(project.getDisease())); - } - return result; - } - - private ProjectMetaData createData(Project project, AuthenticationToken token) { - ProjectMetaData result = new ProjectMetaData(); - ModelData model = modelService.getLastModelByProjectId(project.getProjectId(), token).getModelData(); - - result.setName(project.getName()); - result.setProjectId(project.getProjectId()); - result.setIdObject(project.getId()); - - if (model != null) { - result.setOverviewImageViews(factory.createList(model.getOverviewImages())); - result.setVersion(model.getMapVersion()); - result.setDescription(model.getNotes()); - - Set<OverviewImage> set = new HashSet<OverviewImage>(); - set.addAll(model.getOverviewImages()); - for (OverviewImage image : model.getOverviewImages()) { - for (OverviewLink ol : image.getLinks()) { - if (ol instanceof OverviewImageLink) { - set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); - } - } - } - if (set.size() > 0) { - result.setTopOverviewImage(factory.create(set.iterator().next())); - } else if (model.getOverviewImages().size() > 0) { - logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename()); - result.setTopOverviewImage(factory.create(model.getOverviewImages().get(0))); - } - result.setMap(new ModelMetaData(model)); - - result.setPublicationCount(getPublications(model).size()); - - } - - return result; - } - - private SortedMap<MiriamData, List<AnnotatedObject>> getPublications(ModelData model) { - SortedMap<MiriamData, List<AnnotatedObject>> publications = new TreeMap<>(); - List<ModelData> models = new ArrayList<>(); - for (ModelSubmodelConnection connection : model.getSubmodels()) { - models.add(connection.getSubmodel()); - } - models.add(model); - for (ModelData modelData : models) { - for (Element element : modelData.getElements()) { - for (MiriamData md : element.getMiriamData()) { - if (md.getDataType().equals(MiriamType.PUBMED)) { - List<AnnotatedObject> list = publications.get(md); - if (list == null) { - list = new ArrayList<>(); - publications.put(md, list); - } - list.add(element); - } - } - } - for (Reaction reaction : modelData.getReactions()) { - for (MiriamData md : reaction.getMiriamData()) { - if (md.getDataType().equals(MiriamType.PUBMED)) { - List<AnnotatedObject> list = publications.get(md); - if (list == null) { - list = new ArrayList<>(); - publications.put(md, list); - } - list.add(reaction); - } - } - - } - } - return publications; - } - - /** - * @return the userService - * @see #userService - */ - public IUserService getUserService() { - return userService; - } - - /** - * @param userService - * the userService to set - * @see #userService - */ - public void setUserService(IUserService userService) { - this.userService = userService; - } - - public List<Map<String, Object>> getElements(String projectId, String id, String columns, String token) throws UserAccessException, SecurityException { - Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); - Set<Integer> ids = new HashSet<>(); - if (!id.equals("")) { - for (String str : id.split(",")) { - ids.add(Integer.valueOf(str)); - } - } - Set<String> columnsSet = createElementColumnSet(columns); - - List<Map<String, Object>> result = new ArrayList<>(); - - List<Model> models = new ArrayList<>(); - models.addAll(model.getSubmodels()); - models.add(model); - for (Model model2 : models) { - for (Element element : model2.getElements()) { - if (ids.size() == 0 || ids.contains(element.getId())) { - result.add(preparedElement(element, columnsSet)); - } - } - } - - return result; - } - - public List<Map<String, Object>> getClosestElementsByCoordinates(String projectId, String modelId, String token, Point2D coordinates, Integer count) - throws UserAccessException, SecurityException { - List<Map<String, Object>> resultMap = new ArrayList<>(); - - Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); - - Model submodel = model.getSubmodelById(modelId); - - List<Object> elements = searchService.getClosestElements(submodel, coordinates, count); - for (Object object : elements) { - Map<String, Object> result = createMinifiedSearchResult(object); - resultMap.add(result); - } - return resultMap; - } - - private Map<String, Object> createMinifiedSearchResult(Object object) { - Map<String, Object> result = new HashMap<>(); - if (object instanceof Element) { - result.put("type", ElementIdentifierType.ALIAS); - Element element = (Element) object; - result.put("id", element.getId()); - result.put("modelId", element.getModel().getId()); - } else if (object instanceof Reaction) { - result.put("type", ElementIdentifierType.REACTION); - Reaction element = (Reaction) object; - result.put("id", element.getId()); - result.put("modelId", element.getModel().getId()); - - } else { - throw new InvalidStateException("Unknown type of result: " + object.getClass()); - } - return result; - }; - - public List<Map<String, Object>> getReactions(String projectId, String id, String columns, String token, String participantElementId) - throws UserAccessException, SecurityException { - Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); - Set<Integer> ids = new HashSet<>(); - if (!id.equals("")) { - for (String str : id.split(",")) { - ids.add(Integer.valueOf(str)); - } - } - Set<Element> elementSet = new HashSet<>(); - if (!participantElementId.equals("")) { - for (String str : participantElementId.split(",")) { - elementSet.add(model.getElementByDbId(Integer.valueOf(str))); - } - } - Set<String> columnsSet = createReactionColumnSet(columns); - - List<Map<String, Object>> result = new ArrayList<>(); - - List<Model> models = new ArrayList<>(); - models.addAll(model.getSubmodels()); - models.add(model); - for (Model model2 : models) { - for (Reaction reaction : model2.getReactions()) { - if (ids.size() == 0 || ids.contains(reaction.getId())) { - if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) { - result.add(preparedReaction(reaction, columnsSet)); - } - } - } - } - - return result; - } - - private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) { - for (Element element : elementSet) { - if (reaction.containsElement(element)) { - return true; - } - } - return false; - } - - private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) { - Map<String, Object> result = new HashMap<>(); - for (String string : columnsSet) { - String column = string.toLowerCase(); - Object value = null; - if (column.equals("id") || column.equals("idobject")) { - value = reaction.getId(); - } else if (column.equals("modelid")) { - value = reaction.getModelData().getId(); - } else if (column.equals("reactionid")) { - value = reaction.getIdReaction(); - } else if (column.equals("name")) { - value = reaction.getName(); - } else if (column.equals("centerpoint")) { - value = reaction.getCenterPoint(); - } else if (column.equals("products")) { - List<Integer> ids = new ArrayList<>(); - for (Product product : reaction.getProducts()) { - ids.add(product.getElement().getId()); - } - value = StringUtils.join(ids, ","); - } else if (column.equals("reactants")) { - List<Integer> ids = new ArrayList<>(); - for (Reactant reactant : reaction.getReactants()) { - ids.add(reactant.getElement().getId()); - } - value = StringUtils.join(ids, ","); - } else if (column.equals("modifiers")) { - List<Integer> ids = new ArrayList<>(); - for (Modifier product : reaction.getModifiers()) { - ids.add(product.getElement().getId()); - } - value = StringUtils.join(ids, ","); - } else if (column.equals("type")) { - value = reaction.getStringType(); - } else if (column.equals("hierarchyvisibilitylevel")) { - value = reaction.getVisibilityLevel(); - } else if (column.equals("lines")) { - value = new LightReactionView(reaction).getLines(); - } else { - value = "Unknown column"; - } - result.put(string, value); - } - return result; - } - - private Map<String, Object> preparedElement(Element element, Set<String> columnsSet) { - Map<String, Object> result = new HashMap<>(); - for (String string : columnsSet) { - String column = string.toLowerCase(); - Object value = null; - if (column.equals("id") || column.equals("idobject")) { - value = element.getId(); - } else if (column.equals("modelid")) { - value = element.getModelData().getId(); - } else if (column.equals("name")) { - value = element.getName(); - } else if (column.equals("type")) { - value = element.getStringType(); - } else if (column.equals("symbol")) { - value = element.getSymbol(); - } else if (column.equals("fullname")) { - value = element.getFullName(); - } else if (column.equals("abbreviation")) { - value = element.getAbbreviation(); - } else if (column.equals("compartmentid")) { - if (element.getCompartment() != null) { - value = element.getCompartment().getId(); - } - } else if (column.equals("complexid")) { - if (element instanceof Species) { - if (((Species) element).getComplex() != null) { - value = ((Species) element).getComplex().getId(); - } - } - } else if (column.equals("references")) { - value = annotationViewFactory.createList(element.getMiriamData()); - } else if (column.equals("synonyms")) { - value = element.getSynonyms(); - } else if (column.equals("formula")) { - value = element.getFormula(); - } else if (column.equals("description")) { - value = element.getNotes(); - } else if (column.equals("formersymbols")) { - value = element.getFormerSymbols(); - } else if (column.equals("hierarchyvisibilitylevel")) { - value = element.getVisibilityLevel(); - } else if (column.equals("bounds")) { - value = new Rectangle2D.Double(element.getX(), element.getY(), element.getWidth(), element.getHeight()); - } else { - value = "Unknown column"; - } - result.put(string, value); - } - return result; - } - - private Set<String> createElementColumnSet(String columns) { - Set<String> columnsSet = new HashSet<>(); - if (columns.equals("")) { - columnsSet.add("id"); - columnsSet.add("modelId"); - columnsSet.add("name"); - columnsSet.add("type"); - columnsSet.add("description"); - columnsSet.add("type"); - columnsSet.add("symbol"); - columnsSet.add("complexId"); - columnsSet.add("compartmentId"); - columnsSet.add("fullName"); - columnsSet.add("abbreviation"); - columnsSet.add("formula"); - columnsSet.add("name"); - columnsSet.add("synonyms"); - columnsSet.add("formerSymbols"); - columnsSet.add("references"); - columnsSet.add("bounds"); - columnsSet.add("hierarchyVisibilityLevel"); - } else { - for (String str : columns.split(",")) { - columnsSet.add(str); - } - } - return columnsSet; - } - - private Set<String> createReactionColumnSet(String columns) { - Set<String> columnsSet = new HashSet<>(); - if (columns.equals("")) { - columnsSet.add("id"); - columnsSet.add("reactionId"); - columnsSet.add("modelId"); - columnsSet.add("type"); - columnsSet.add("lines"); - columnsSet.add("centerPoint"); - columnsSet.add("products"); - columnsSet.add("reactants"); - columnsSet.add("modifiers"); - columnsSet.add("hierarchyVisibilityLevel"); - } else { - for (String str : columns.split(",")) { - columnsSet.add(str); - } - } - return columnsSet; - } - - /** - * @return the modelService - * @see #modelService - */ - public IModelService getModelService() { - return modelService; - } - - /** - * @param modelService - * the modelService to set - * @see #modelService - */ - public void setModelService(IModelService modelService) { - this.modelService = modelService; - } - - /** - * @return the searchService - * @see #searchService - */ - public ISearchService getSearchService() { - return searchService; - } - - /** - * @param searchService - * the searchService to set - * @see #searchService - */ - public void setSearchService(ISearchService searchService) { - this.searchService = searchService; - } - - public List<Map<String, Object>> getElementsByQuery(String projectId, String token, String query, Integer maxElements, String perfectMatch) - throws SecurityException { - List<Map<String, Object>> resultMap = new ArrayList<>(); - - Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); - - Integer limit = Integer.valueOf(maxElements); - boolean match = perfectMatch.equals("true"); - List<Object> elements = searchService.searchByQuery(model, query, limit, match); - for (Object object : elements) { - Map<String, Object> result = createMinifiedSearchResult(object); - resultMap.add(result); - } - return resultMap; - } - - public String[] getSuggestedQueryList(String projectId, String token) throws SecurityException { - Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); - return searchService.getSuggestedQueryList(model); - } - - /** - * @return the factory - * @see #factory - */ - public OverviewImageViewFactory getFactory() { - return factory; - } - - /** - * @param factory - * the factory to set - * @see #factory - */ - public void setFactory(OverviewImageViewFactory factory) { - this.factory = factory; - } - - public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException { - AuthenticationToken authenticationToken = userService.getToken(token); - Project project = projectService.getProjectByProjectId(projectId, authenticationToken); - if (project == null) { - throw new QueryException("Project with given id doesn't exist"); - } - FileEntry entry = new UploadedFileEntry(); - entry.setOriginalFileName(project.getInputFileName()); - entry.setFileContent(project.getInputData()); - return entry; - } - - public Map<String, Object> getPublications(String projectId, String token, String startString, Integer length) throws SecurityException, QueryException { - AuthenticationToken authenticationToken = userService.getToken(token); - Model model = modelService.getLastModelByProjectId(projectId, authenticationToken); - if (model == null) { - throw new QueryException("Project with given id doesn't exist"); - } - - Integer start = Math.max(0, Integer.valueOf(startString)); - List<Map<String, Object>> resultList = new ArrayList<>(); - - SortedMap<MiriamData, List<AnnotatedObject>> publications = getPublications(model.getModelData()); - int index = 0; - Set<String> columns = new HashSet<>(); - columns.add("id"); - columns.add("type"); - columns.add("modelid"); - for (Map.Entry<MiriamData, List<AnnotatedObject>> entry : publications.entrySet()) { - if (index >= start && index < start + length) { - List<Object> elements = new ArrayList<>(); - for (AnnotatedObject object : entry.getValue()) { - elements.add(createMinifiedSearchResult(object)); - } - - Map<String, Object> row = new HashMap<>(); - row.put("elements", elements); - if (entry.getKey().getDataType().equals(MiriamType.PUBMED)) { - try { - row.put("publication", pubmedParser.getPubmedArticleById(Integer.valueOf(entry.getKey().getResource()))); - } catch (Exception e) { - logger.error(e, e); - row.put("publication", annotationViewFactory.create(entry.getKey())); - } - } else { - row.put("publication", annotationViewFactory.create(entry.getKey())); - } - resultList.add(row); - } - index++; - - } - - Map<String, Object> result = new HashMap<>(); - result.put("data", resultList); - result.put("totalSize", publications.size()); - result.put("start", start); - result.put("length", resultList.size()); - return result; - } - - public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, - String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException { - AuthenticationToken authenticationToken = userService.getToken(token); - User user = userService.getUserByToken(authenticationToken); - - Model topModel = modelService.getLastModelByProjectId(projectId, authenticationToken); - if (topModel == null) { - throw new QueryException("Project with given id doesn't exist"); - } - - Model originalModel = topModel.getSubmodelById(modelId); - - if (originalModel == null) { - throw new QueryException("Model with given id doesn't exist"); - } - - Layout layout = null; - if (!backgroundOverlayId.equals("")) { - layout = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId)); - - if (layout == null) { - throw new QueryException("Unknown layout in model. Layout.id=" + backgroundOverlayId); - } - } - - Model colorModel = new CopyCommand(originalModel).execute(); - if (layout != null) { - if (layout.getInputData() != null) { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection<ColorSchema> schemas = reader.readColorSchema(layout.getInputData().getFileContent()); - - new ColorModelCommand(colorModel, schemas, userService.getColorExtractorForUser(user)).execute(); - } else if (layout.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { - // this might not return true if we change CLEAN.title in future... - - // if it's clean then remove coloring - new ClearColorModelCommand(colorModel).execute(); - } - } - for (Element alias : colorModel.getElements()) { - alias.setVisibilityLevel(0); - } - - Integer level = Configuration.MIN_ZOOM_LEVEL; - if (!zoomLevel.equals("")) { - level = Integer.valueOf(zoomLevel); - } - - // transform polygon - CoordinationConverter cc = new CoordinationConverter(colorModel); - Double minX = originalModel.getWidth(); - Double minY = originalModel.getHeight(); - Double maxX = 0.0; - Double maxY = 0.0; - if (!polygonString.equals("")) { - Path2D polygon = cc.latLngToPolygon(polygonString); - - PathIterator pathIter = polygon.getPathIterator(null); - while (!pathIter.isDone()) { - final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE]; - if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) { - minX = Math.min(minX, segment[0]); - maxX = Math.max(maxX, segment[0]); - minY = Math.min(minY, segment[1]); - maxY = Math.max(maxY, segment[1]); - } - pathIter.next(); - } - } else { - maxX = originalModel.getWidth(); - maxY = originalModel.getHeight(); - minX = 0.0; - minY = 0.0; - } - - maxX = Math.min(originalModel.getWidth(), maxX); - maxY = Math.min(originalModel.getHeight(), maxY); - minX = Math.max(0.0, minX); - minY = Math.max(0.0, minY); - - Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize()); - - for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) { - scale /= 2; - } - - ColorExtractor colorExtractor = userService.getColorExtractorForUser(user); - - Params params = new Params().// - x(minX).// - y(minY).// - height((maxY - minY) / scale).// - width((maxX - minX) / scale).// - level(level).// - nested(false).// automatically set nested view as invalid - scale(scale).// - minColor(colorExtractor.getMinColor()).// - maxColor(colorExtractor.getMaxColor()).// - sbgn(topModel.getProject().isSbgnFormat()).// - model(colorModel); - List<Integer> visibleLayoutIds = deserializeIdList(overlayIds); - for (Integer integer : visibleLayoutIds) { - Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken); - params.addVisibleLayout(map); - } - - ImageGenerators imageGenerator = new ImageGenerators(); - String extension = imageGenerator.getExtension(handlerClass); - File file = File.createTempFile("map", "." + extension); - - imageGenerator.generate(handlerClass, params, file.getAbsolutePath()); - - FileEntry entry = new UploadedFileEntry(); - entry.setOriginalFileName("map." + extension); - entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file))); - file.delete(); - return entry; - - } - - private List<Integer> deserializeIdList(String overlayIds) { - List<Integer> result = new ArrayList<>(); - String[] tmp = overlayIds.split(","); - for (String string : tmp) { - if (!string.equals("")) { - result.add(Integer.valueOf(string)); - } - } - return result; - } - - public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, - String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, - ConverterException, InconsistentModelException { - AuthenticationToken authenticationToken = userService.getToken(token); - - Model topModel = modelService.getLastModelByProjectId(projectId, authenticationToken); - if (topModel == null) { - throw new QueryException("Project with given id doesn't exist"); - } - - Model originalModel = topModel.getSubmodelById(modelId); - - if (originalModel == null) { - throw new QueryException("Model with given id doesn't exist"); - } - - CoordinationConverter cc = new CoordinationConverter(originalModel); - Path2D polygon = cc.latLngToPolygon(polygonString); - - // create model bounded by the polygon - SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon); - Model part = subModelCommand.execute(); - - IConverter parser; - if (SbgnmlXmlConverter.class.getCanonicalName().equals(handlerClass)) { - parser = new SbgnmlXmlConverter(); - } else if (CellDesignerXmlParser.class.getCanonicalName().equals(handlerClass)) { - parser = new CellDesignerXmlParser(); - } else { - throw new QueryException("Unknown handlerClass: " + handlerClass); - } - InputStream is = parser.exportModelToInputStream(part); - - String fileExtension = parser.getFileExtension(); - - FileEntry entry = new UploadedFileEntry(); - entry.setOriginalFileName("model." + fileExtension); - entry.setFileContent(IOUtils.toByteArray(is)); - return entry; - - } - - /** - * @return the pubmedParser - * @see #pubmedParser - */ - public PubmedParser getPubmedParser() { - return pubmedParser; - } - - /** - * @param pubmedParser - * the pubmedParser to set - * @see #pubmedParser - */ - public void setPubmedParser(PubmedParser pubmedParser) { - this.pubmedParser = pubmedParser; - } - -} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ModelMetaData.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ModelMetaData.java similarity index 94% rename from rest-api/src/main/java/lcsb/mapviewer/api/project/ModelMetaData.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/ModelMetaData.java index 3fc4c467e5de927098a794299f5d95cfb1683248..3655852451e9b442963b82282fb8c99ad6f9e2f8 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ModelMetaData.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ModelMetaData.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.project; +package lcsb.mapviewer.api.projects; import java.awt.geom.Point2D; import java.io.Serializable; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java new file mode 100644 index 0000000000000000000000000000000000000000..c96698f1cffafc53ec942c1f3c30f38691c55159 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java @@ -0,0 +1,97 @@ +package lcsb.mapviewer.api.projects; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.commands.CommandExecutionException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.converter.ConverterException; +import lcsb.mapviewer.model.cache.FileEntry; +import lcsb.mapviewer.model.map.InconsistentModelException; +import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class ProjectController extends BaseController { + @Autowired + private ProjectRestImpl projectController; + + @RequestMapping(value = "/projects/{projectId}", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ProjectMetaData getMetaData(// + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException { + return projectController.getMetaData(projectId, token); + } + + @RequestMapping(value = "/projects/{projectId}:downloadSource", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getProjectSource(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId // + ) throws SecurityException, QueryException { + + FileEntry file = projectController.getSource(token, projectId); + MediaType type = MediaType.TEXT_PLAIN; + if (file.getOriginalFileName().endsWith("xml")) { + type = MediaType.APPLICATION_XML; + } else if (file.getOriginalFileName().endsWith("zip")) { + type = MediaType.APPLICATION_OCTET_STREAM; + } + return ResponseEntity + .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadImage", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getModelAsImage(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "handlerClass") String handlerClass, // + @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // + @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // + @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // + @RequestParam(value = "polygonString", defaultValue = "") String polygonString// + ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException { + + FileEntry file = projectController.getModelAsImage(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); + MediaType type = MediaType.APPLICATION_OCTET_STREAM; + return ResponseEntity + .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}:downloadModel", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getModelAsModelFile(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "handlerClass") String handlerClass, // + @RequestParam(value = "backgroundOverlayId", defaultValue = "") String backgroundOverlayId, // + @RequestParam(value = "overlayIds", defaultValue = "") String overlayIds, // + @RequestParam(value = "zoomLevel", defaultValue = "") String zoomLevel, // + @RequestParam(value = "polygonString", defaultValue = "") String polygonString// + ) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, ConverterException, + InconsistentModelException { + + FileEntry file = projectController.getModelAsModelFile(token, projectId, modelId, handlerClass, backgroundOverlayId, overlayIds, zoomLevel, polygonString); + MediaType type = MediaType.APPLICATION_OCTET_STREAM; + return ResponseEntity + .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectMetaData.java similarity index 93% rename from rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectMetaData.java index 6c946ee3d0b1b3ac4674e7e49c52281bc42549ec..1be0b0250fb4044c9e0b6be62bab0959e70f8a97 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/project/ProjectMetaData.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectMetaData.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.project; +package lcsb.mapviewer.api.projects; import java.io.Serializable; import java.util.List; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..d3182f0880ec74f8d3d52d341dc7fa57b0e51e41 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java @@ -0,0 +1,381 @@ +package lcsb.mapviewer.api.projects; + +import java.awt.geom.Path2D; +import java.awt.geom.PathIterator; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestParam; + +import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.api.projects.models.publications.PublicationsRestImpl; +import lcsb.mapviewer.commands.ClearColorModelCommand; +import lcsb.mapviewer.commands.ColorExtractor; +import lcsb.mapviewer.commands.ColorModelCommand; +import lcsb.mapviewer.commands.CommandExecutionException; +import lcsb.mapviewer.commands.CopyCommand; +import lcsb.mapviewer.commands.SubModelCommand; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.converter.ConverterException; +import lcsb.mapviewer.converter.IConverter; +import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; +import lcsb.mapviewer.converter.graphics.ImageGenerators; +import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.converter.model.sbgnml.SbgnmlXmlConverter; +import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.cache.FileEntry; +import lcsb.mapviewer.model.cache.UploadedFileEntry; +import lcsb.mapviewer.model.map.InconsistentModelException; +import lcsb.mapviewer.model.map.OverviewImage; +import lcsb.mapviewer.model.map.OverviewImageLink; +import lcsb.mapviewer.model.map.OverviewLink; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; +import lcsb.mapviewer.model.map.layout.Layout; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.interfaces.ILayoutService; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.interfaces.IProjectService; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.utils.ColorSchemaReader; +import lcsb.mapviewer.services.utils.data.BuildInLayout; +import lcsb.mapviewer.services.utils.gmap.CoordinationConverter; +import lcsb.mapviewer.services.view.AnnotationViewFactory; +import lcsb.mapviewer.services.view.AuthenticationToken; +import lcsb.mapviewer.services.view.OverviewImageViewFactory; + +@Transactional(value = "txManager") +public class ProjectRestImpl extends BaseRestImpl { + + /** + * Constant defining size of the array returned by + * {@link PathIterator#currentSegment(double[])} method. More nformation can + * be found <a href= + * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])" + * >here</a> + */ + private static final int PATH_ITERATOR_SEGMENT_SIZE = 6; + + Logger logger = Logger.getLogger(ProjectRestImpl.class); + + @Autowired + private IUserService userService; + + @Autowired + private IProjectService projectService; + + @Autowired + private IModelService modelService; + + @Autowired + private PublicationsRestImpl publicationsRestImpl; + + @Autowired + private AnnotationViewFactory annotationViewFactory; + + @Autowired + private ILayoutService layoutService; + + @Autowired + private OverviewImageViewFactory factory; + + public ProjectMetaData getMetaData(String projectId, String token) throws SecurityException { + AuthenticationToken authenticationToken = userService.getToken(token); + Project project = projectService.getProjectByProjectId(projectId, authenticationToken); + ProjectMetaData result = createData(project, authenticationToken); + if (project.getOrganism() != null) { + result.setOrganism(annotationViewFactory.create(project.getOrganism())); + } + if (project.getDisease() != null) { + result.setDisease(annotationViewFactory.create(project.getDisease())); + } + return result; + } + + private ProjectMetaData createData(Project project, AuthenticationToken token) { + ProjectMetaData result = new ProjectMetaData(); + Model model = modelService.getLastModelByProjectId(project.getProjectId(), token); + + result.setName(project.getName()); + result.setProjectId(project.getProjectId()); + result.setIdObject(project.getId()); + + if (model != null) { + result.setOverviewImageViews(factory.createList(model.getOverviewImages())); + result.setVersion(model.getMapVersion()); + result.setDescription(model.getNotes()); + + Set<OverviewImage> set = new HashSet<OverviewImage>(); + set.addAll(model.getOverviewImages()); + for (OverviewImage image : model.getOverviewImages()) { + for (OverviewLink ol : image.getLinks()) { + if (ol instanceof OverviewImageLink) { + set.remove(((OverviewImageLink) ol).getLinkedOverviewImage()); + } + } + } + if (set.size() > 0) { + result.setTopOverviewImage(factory.create(set.iterator().next())); + } else if (model.getOverviewImages().size() > 0) { + logger.warn("Cannot determine top level image. Taking first one. " + model.getOverviewImages().get(0).getFilename()); + result.setTopOverviewImage(factory.create(model.getOverviewImages().get(0))); + } + result.setMap(new ModelMetaData(model)); + + List<Model> models = new ArrayList<>(); + models.add(model); + models.addAll(model.getSubmodels()); + result.setPublicationCount(publicationsRestImpl.getPublications(models).size()); + + } + + return result; + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + + /** + * @return the factory + * @see #factory + */ + public OverviewImageViewFactory getFactory() { + return factory; + } + + /** + * @param factory + * the factory to set + * @see #factory + */ + public void setFactory(OverviewImageViewFactory factory) { + this.factory = factory; + } + + public FileEntry getSource(String token, String projectId) throws SecurityException, QueryException { + AuthenticationToken authenticationToken = userService.getToken(token); + Project project = projectService.getProjectByProjectId(projectId, authenticationToken); + if (project == null) { + throw new QueryException("Project with given id doesn't exist"); + } + FileEntry entry = new UploadedFileEntry(); + entry.setOriginalFileName(project.getInputFileName()); + entry.setFileContent(project.getInputData()); + return entry; + } + + public FileEntry getModelAsImage(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, + String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException { + AuthenticationToken authenticationToken = userService.getToken(token); + User user = userService.getUserByToken(authenticationToken); + + Model topModel = modelService.getLastModelByProjectId(projectId, authenticationToken); + if (topModel == null) { + throw new QueryException("Project with given id doesn't exist"); + } + + Model originalModel = topModel.getSubmodelById(modelId); + + if (originalModel == null) { + throw new QueryException("Model with given id doesn't exist"); + } + + Layout layout = null; + if (!backgroundOverlayId.equals("")) { + layout = topModel.getLayoutByIdentifier(Integer.valueOf(backgroundOverlayId)); + + if (layout == null) { + throw new QueryException("Unknown layout in model. Layout.id=" + backgroundOverlayId); + } + } + + Model colorModel = new CopyCommand(originalModel).execute(); + if (layout != null) { + if (layout.getInputData() != null) { + ColorSchemaReader reader = new ColorSchemaReader(); + Collection<ColorSchema> schemas = reader.readColorSchema(layout.getInputData().getFileContent()); + + new ColorModelCommand(colorModel, schemas, userService.getColorExtractorForUser(user)).execute(); + } else if (layout.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { + // this might not return true if we change CLEAN.title in future... + + // if it's clean then remove coloring + new ClearColorModelCommand(colorModel).execute(); + } + } + for (Element alias : colorModel.getElements()) { + alias.setVisibilityLevel(0); + } + + Integer level = Configuration.MIN_ZOOM_LEVEL; + if (!zoomLevel.equals("")) { + level = Integer.valueOf(zoomLevel); + } + + // transform polygon + CoordinationConverter cc = new CoordinationConverter(colorModel); + Double minX = originalModel.getWidth(); + Double minY = originalModel.getHeight(); + Double maxX = 0.0; + Double maxY = 0.0; + Path2D polygon = cc.latLngToPolygon(polygonString); + + PathIterator pathIter = polygon.getPathIterator(null); + while (!pathIter.isDone()) { + final double[] segment = new double[PATH_ITERATOR_SEGMENT_SIZE]; + if (pathIter.currentSegment(segment) != PathIterator.SEG_CLOSE) { + minX = Math.min(minX, segment[0]); + maxX = Math.max(maxX, segment[0]); + minY = Math.min(minY, segment[1]); + maxY = Math.max(maxY, segment[1]); + } + pathIter.next(); + } + + maxX = Math.min(originalModel.getWidth(), maxX); + maxY = Math.min(originalModel.getHeight(), maxY); + minX = Math.max(0.0, minX); + minY = Math.max(0.0, minY); + + Double scale = Math.max(originalModel.getHeight(), originalModel.getWidth()) / (originalModel.getTileSize()); + + for (int i = level; i > Configuration.MIN_ZOOM_LEVEL; i--) { + scale /= 2; + } + + ColorExtractor colorExtractor = userService.getColorExtractorForUser(user); + + Params params = new Params().// + x(minX).// + y(minY).// + height((maxY - minY) / scale).// + width((maxX - minX) / scale).// + level(level).// + nested(false).// automatically set nested view as invalid + scale(scale).// + minColor(colorExtractor.getMinColor()).// + maxColor(colorExtractor.getMaxColor()).// + sbgn(topModel.getProject().isSbgnFormat()).// + model(colorModel); + List<Integer> visibleLayoutIds = deserializeIdList(overlayIds); + for (Integer integer : visibleLayoutIds) { + Map<Object, ColorSchema> map = layoutService.getElementsForLayout(colorModel, integer, authenticationToken); + params.addVisibleLayout(map); + } + + ImageGenerators imageGenerator = new ImageGenerators(); + String extension = imageGenerator.getExtension(handlerClass); + File file = File.createTempFile("map", "." + extension); + + imageGenerator.generate(handlerClass, params, file.getAbsolutePath()); + + FileEntry entry = new UploadedFileEntry(); + entry.setOriginalFileName("map." + extension); + entry.setFileContent(IOUtils.toByteArray(new FileInputStream(file))); + file.delete(); + return entry; + + } + + private List<Integer> deserializeIdList(String overlayIds) { + List<Integer> result = new ArrayList<>(); + String[] tmp = overlayIds.split(","); + for (String string : tmp) { + if (!string.equals("")) { + result.add(Integer.valueOf(string)); + } + } + return result; + } + + public FileEntry getModelAsModelFile(String token, String projectId, String modelId, String handlerClass, String backgroundOverlayId, String overlayIds, + String zoomLevel, String polygonString) throws SecurityException, QueryException, IOException, InvalidColorSchemaException, CommandExecutionException, + ConverterException, InconsistentModelException { + AuthenticationToken authenticationToken = userService.getToken(token); + + Model topModel = modelService.getLastModelByProjectId(projectId, authenticationToken); + if (topModel == null) { + throw new QueryException("Project with given id doesn't exist"); + } + + Model originalModel = topModel.getSubmodelById(modelId); + + if (originalModel == null) { + throw new QueryException("Model with given id doesn't exist"); + } + + CoordinationConverter cc = new CoordinationConverter(originalModel); + Path2D polygon = cc.latLngToPolygon(polygonString); + + // create model bounded by the polygon + SubModelCommand subModelCommand = new SubModelCommand(originalModel, polygon); + Model part = subModelCommand.execute(); + + IConverter parser; + if (SbgnmlXmlConverter.class.getCanonicalName().equals(handlerClass)) { + parser = new SbgnmlXmlConverter(); + } else if (CellDesignerXmlParser.class.getCanonicalName().equals(handlerClass)) { + parser = new CellDesignerXmlParser(); + } else { + throw new QueryException("Unknown handlerClass: " + handlerClass); + } + InputStream is = parser.exportModelToInputStream(part); + + String fileExtension = parser.getFileExtension(); + + FileEntry entry = new UploadedFileEntry(); + entry.setOriginalFileName("model." + fileExtension); + entry.setFileContent(IOUtils.toByteArray(is)); + return entry; + + } + +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalController.java new file mode 100644 index 0000000000000000000000000000000000000000..95cdfe87f7512719d1860a4c7bda61f9cb2dc170 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalController.java @@ -0,0 +1,46 @@ +package lcsb.mapviewer.api.projects.chemicals; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class ChemicalController extends BaseController { + + @Autowired + private ChemicalRestImpl chemicalController; + + @RequestMapping(value = "/projects/{projectId}/chemicals:search", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getChemicalsByQuery(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @RequestParam(value = "query", defaultValue = "") String query, // + @RequestParam(value = "target", defaultValue = "") String target // + ) throws SecurityException, QueryException { + if (!query.equals("")) { + return chemicalController.getChemicalsByQuery(token, projectId, columns, query); + } else if (target.indexOf(":") >= 0) { + String targetType = target.split(":", -1)[0]; + String targetId = target.split(":", -1)[1]; + return chemicalController.getChemicalsByTarget(token, projectId, targetType, targetId, columns); + } else { + return new ArrayList<>(); + } + } +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalRestImpl.java similarity index 96% rename from rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalRestImpl.java index 95ae96b40699465c82ed87ddc0245f29a7a57b31..93febcd23ce73b14718a5d89729b5655bf027431 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/chemical/ChemicalRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/chemicals/ChemicalRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.chemical; +package lcsb.mapviewer.api.projects.chemicals; import java.util.ArrayList; import java.util.Collection; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java new file mode 100644 index 0000000000000000000000000000000000000000..aaff441f0d5f47f65028f5fce68690e47b3554b7 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentController.java @@ -0,0 +1,164 @@ +package lcsb.mapviewer.api.projects.comments; + +import java.awt.geom.Point2D; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; + +@RestController +public class CommentController extends BaseController { + + @Autowired + private CommentRestImpl commentController; + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getComments(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @RequestParam(value = "removed", defaultValue = "") String removed // + ) throws SecurityException, QueryException { + return commentController.getCommentList(token, projectId, columns, "", "", removed); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getCommentsByReaction(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @PathVariable(value = "reactionId") String reactionId, // + @RequestParam(value = "removed", defaultValue = "") String removed // + ) throws SecurityException, QueryException { + return commentController.getCommentList(token, projectId, columns, reactionId, ElementIdentifierType.REACTION.getJsName(), removed); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getCommentsByElement(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @PathVariable(value = "elementId") String elementId, // + @RequestParam(value = "removed", defaultValue = "") String removed // + ) throws SecurityException, QueryException { + return commentController.getCommentList(token, projectId, columns, elementId, ElementIdentifierType.ALIAS.getJsName(), removed); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates}", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getCommentsByPoint(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @PathVariable(value = "coordinates") String coordinates, // + @RequestParam(value = "removed", defaultValue = "") String removed // + ) throws SecurityException, QueryException { + return commentController.getCommentList(token, projectId, columns, coordinates, ElementIdentifierType.POINT.getJsName(), removed); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/elements/{elementId}", method = { RequestMethod.POST }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> addCommentForElement(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "elementId") String elementId, // + @RequestParam(value = "name") String name, // + @RequestParam(value = "email") String email, // + @RequestParam(value = "content") String content, // + @RequestParam(value = "pinned", defaultValue = "true") String pinned, // + @RequestParam(value = "coordinates") String coordinates, // + @PathVariable(value = "modelId") String modelId // + ) throws SecurityException, QueryException { + Point2D pointCoordinates = parseCoordinates(coordinates); + return commentController.addComment( + token, projectId, ElementIdentifierType.ALIAS.getJsName(), elementId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates, + modelId); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/bioEntities/reactions/{reactionId}", method = { RequestMethod.POST }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> addCommentForReaction(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "reactionId") String reactionId, // + @RequestParam(value = "name") String name, // + @RequestParam(value = "email") String email, // + @RequestParam(value = "content") String content, // + @RequestParam(value = "pinned", defaultValue = "true") String pinned, // + @RequestParam(value = "coordinates") String coordinates, // + @PathVariable(value = "modelId") String modelId // + ) throws SecurityException, QueryException { + Point2D pointCoordinates = parseCoordinates(coordinates); + return commentController.addComment( + token, projectId, ElementIdentifierType.REACTION.getJsName(), reactionId, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates, + modelId); + } + + @RequestMapping(value = "/projects/{projectId}/comments/models/{modelId}/points/{coordinates}", method = { RequestMethod.POST }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> addCommentForPoint(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "name") String name, // + @RequestParam(value = "email") String email, // + @RequestParam(value = "content") String content, // + @RequestParam(value = "pinned", defaultValue = "true") String pinned, // + @PathVariable(value = "coordinates") String coordinates, // + @PathVariable(value = "modelId") String modelId // + ) throws SecurityException, QueryException { + Point2D pointCoordinates = parseCoordinates(coordinates); + return commentController.addComment( + token, projectId, ElementIdentifierType.POINT.getJsName(), coordinates, name, email, content, pinned.toLowerCase().equals("true"), pointCoordinates, + modelId); + } + + private Point2D parseCoordinates(String coordinates) throws QueryException { + String[] tmp = coordinates.split(","); + if (tmp.length != 2) { + throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'"); + } + Double x = null; + Double y = null; + try { + x = Double.valueOf(tmp[0]); + y = Double.valueOf(tmp[1]); + } catch (NumberFormatException e) { + throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e); + } + Point2D pointCoordinates = new Point2D.Double(x, y); + return pointCoordinates; + } + + /** + * @return the overlayController + * @see #commentController + */ + public CommentRestImpl getOverlayController() { + return commentController; + } + + /** + * @param overlayController + * the overlayController to set + * @see #commentController + */ + public void setOverlayController(CommentRestImpl overlayController) { + this.commentController = overlayController; + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java similarity index 92% rename from rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java index ad9ae26a8b95e0c8f6dd675dfe01e4ecfebb4d8e..f4fbd153e16d2ee6ca68e184c015db93ffde0348 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/comment/CommentRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/comments/CommentRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.comment; +package lcsb.mapviewer.api.projects.comments; import java.awt.geom.Point2D; import java.util.ArrayList; @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.api.ObjectNotFoundException; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.map.Comment; @@ -325,7 +326,7 @@ public class CommentRestImpl extends BaseRestImpl { AuthenticationToken authenticationToken = userService.getToken(token); Model model = modelService.getLastModelByProjectId(projectId, authenticationToken); if (model == null) { - throw new QueryException("Project with given id doesn't exist"); + throw new ObjectNotFoundException("Project with given id doesn't exist"); } Integer modelId = null; @@ -355,8 +356,11 @@ public class CommentRestImpl extends BaseRestImpl { throw new QueryException("Unknown type of commented object: " + elementType); } - commentService.addComment(name, email, content, model, pointCoordinates, commentedObject, pinned, submodel); - return okStatus(); + Comment comment = commentService.addComment(name, email, content, model, pointCoordinates, commentedObject, pinned, submodel); + + Project project = model.getProject(); + boolean isAdmin = userService.userHasPrivilege(authenticationToken, PrivilegeType.EDIT_COMMENTS_PROJECT, project); + return preparedComment(comment, createCommentColumnSet("", isAdmin), isAdmin); } } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugController.java new file mode 100644 index 0000000000000000000000000000000000000000..7afb8ed73fe31c4b2ba91b1a0e7e84338b1e2b70 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugController.java @@ -0,0 +1,45 @@ +package lcsb.mapviewer.api.projects.drugs; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class DrugController extends BaseController { + + @Autowired + private DrugRestImpl drugController; + + @RequestMapping(value = "/projects/{projectId}/drugs:search", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getDrugsByQuery(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @RequestParam(value = "query", defaultValue = "") String query, // + @RequestParam(value = "target", defaultValue = "") String target // + ) throws SecurityException, QueryException { + if (!query.equals("")) { + return drugController.getDrugsByQuery(token, projectId, columns, query); + } else if (target.indexOf(":") >= 0) { + String targetType = target.split(":", -1)[0]; + String targetId = target.split(":", -1)[1]; + return drugController.getDrugsByTarget(token, projectId, targetType, targetId, columns); + } else { + return new ArrayList<>(); + } + } +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugRestImpl.java similarity index 96% rename from rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugRestImpl.java index 7cd39fa65588c11d83957d14ef68f3357257ab81..f7ec8bcfb8c201cc49df0a229cd872e8491b07b8 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/drug/DrugRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/drugs/DrugRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.drug; +package lcsb.mapviewer.api.projects.drugs; import java.util.ArrayList; import java.util.Collection; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaController.java new file mode 100644 index 0000000000000000000000000000000000000000..9450f9d5356e787471f57113cd2342b670132bd4 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaController.java @@ -0,0 +1,46 @@ +package lcsb.mapviewer.api.projects.mirnas; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class MiRnaController extends BaseController { + + @Autowired + private MiRnaRestImpl miRnaController; + + @RequestMapping(value = "/projects/{projectId}/miRnas:search", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getMiRnasByQuery(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @RequestParam(value = "query", defaultValue = "") String query, // + @RequestParam(value = "target", defaultValue = "") String target // + ) throws SecurityException, QueryException { + if (!query.equals("")) { + return miRnaController.getMiRnasByQuery(token, projectId, columns, query); + } else if (target.indexOf(":") >= 0) { + String targetType = target.split(":", -1)[0]; + String targetId = target.split(":", -1)[1]; + return miRnaController.getMiRnasByTarget(token, projectId, targetType, targetId, columns); + } else { + return new ArrayList<>(); + } + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaRestImpl.java similarity index 96% rename from rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaRestImpl.java index 9041e2d84814ff96c9cfffe4557c34e3d282edee..c597bcd68931634f9d310ddddc3f1e30e3ece4a8 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/mirnas/MiRnaRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.mirna; +package lcsb.mapviewer.api.projects.mirnas; import java.util.ArrayList; import java.util.Collection; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesController.java new file mode 100644 index 0000000000000000000000000000000000000000..9f8bd3fe86291062473e0240e67a49eef7a7cfa1 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesController.java @@ -0,0 +1,78 @@ +package lcsb.mapviewer.api.projects.models.bioEntities; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class BioEntitiesController extends BaseController { + @Autowired + private BioEntitiesRestImpl bioEntitiesRestImpl; + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities:search", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getClosestElementsByCoordinates(// + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @RequestParam(value = "coordinates", defaultValue = "") String coordinates, // + @RequestParam(value = "query", defaultValue = "") String query, // + @RequestParam(value = "count", defaultValue = "") String count, // + @RequestParam(value = "perfectMatch", defaultValue = "false") String perfectMatch// + ) throws QueryException, SecurityException { + if (!coordinates.trim().isEmpty()) { + if (modelId.equals("*")) { + throw new QueryException("modelId must be defined when searching by coordinates"); + } + if (count.trim().isEmpty()) { + count = "5"; + } + String[] tmp = coordinates.split(","); + if (tmp.length != 2) { + throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'"); + } + Double x = null; + Double y = null; + try { + x = Double.valueOf(tmp[0]); + y = Double.valueOf(tmp[1]); + } catch (NumberFormatException e) { + throw new QueryException("Coordinates must be in the format: 'xxx.xx,yyy.yy'", e); + } + Point2D pointCoordinates = new Point2D.Double(x, y); + return bioEntitiesRestImpl.getClosestElementsByCoordinates(projectId, modelId, token, pointCoordinates, Integer.valueOf(count), perfectMatch); + } else if (!query.trim().isEmpty()) { + if (count.trim().isEmpty()) { + count = "100"; + } + return bioEntitiesRestImpl.getElementsByQuery(projectId, token, modelId, query, Integer.valueOf(count), perfectMatch); + } else { + return new ArrayList<>(); + } + } + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/suggestedQueryList", method = { RequestMethod.GET, RequestMethod.POST }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public String[] getSuggestedQueryList( // + @PathVariable(value = "projectId") String projectId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token// + ) throws SecurityException { + return bioEntitiesRestImpl.getSuggestedQueryList(projectId, token); + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesRestImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..a82e66e114699e9ec8a1ca8a64c3323036b37bf2 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesRestImpl.java @@ -0,0 +1,126 @@ +package lcsb.mapviewer.api.projects.models.bioEntities; + +import java.awt.geom.Point2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.UserAccessException; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.interfaces.ISearchService; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.view.AnnotationViewFactory; + +@Transactional(value = "txManager") +public class BioEntitiesRestImpl extends BaseRestImpl { + + Logger logger = Logger.getLogger(BioEntitiesRestImpl.class); + + @Autowired + private IUserService userService; + + @Autowired + private IModelService modelService; + + @Autowired + private ISearchService searchService; + + @Autowired + AnnotationViewFactory annotationViewFactory; + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + public List<Map<String, Object>> getClosestElementsByCoordinates(String projectId, String modelId, String token, Point2D coordinates, Integer count, + String perfectMatch) throws UserAccessException, SecurityException { + List<Map<String, Object>> resultMap = new ArrayList<>(); + + Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); + + Model submodel = model.getSubmodelById(modelId); + + List<Object> elements = searchService.getClosestElements(submodel, coordinates, count, perfectMatch.equalsIgnoreCase("true")); + for (Object object : elements) { + Map<String, Object> result = createMinifiedSearchResult(object); + resultMap.add(result); + } + return resultMap; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + + /** + * @return the searchService + * @see #searchService + */ + public ISearchService getSearchService() { + return searchService; + } + + /** + * @param searchService + * the searchService to set + * @see #searchService + */ + public void setSearchService(ISearchService searchService) { + this.searchService = searchService; + } + + public List<Map<String, Object>> getElementsByQuery(String projectId, String token, String modelId, String query, Integer maxElements, String perfectMatch) + throws SecurityException { + List<Map<String, Object>> resultMap = new ArrayList<>(); + + Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); + + Integer limit = Integer.valueOf(maxElements); + boolean match = perfectMatch.equals("true"); + List<Object> elements = searchService.searchByQuery(model, query, limit, match); + for (Object object : elements) { + Map<String, Object> result = createMinifiedSearchResult(object); + resultMap.add(result); + } + return resultMap; + } + + public String[] getSuggestedQueryList(String projectId, String token) throws SecurityException { + Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); + return searchService.getSuggestedQueryList(model); + } + +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java new file mode 100644 index 0000000000000000000000000000000000000000..c6e8f637fb2313650c7a23bda13c6a34850b4f20 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java @@ -0,0 +1,36 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.elements; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class ElementsController extends BaseController { + @Autowired + private ElementsRestImpl projectController; + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/elements/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getElements(// + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "id", defaultValue = "") String id, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token// + ) throws SecurityException { + return projectController.getElements(projectId, id, columns, modelId, token); + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..3ea9f3d76aeb39e06321a94d646a2a7c13d3f106 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java @@ -0,0 +1,185 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.elements; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.UserAccessException; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.view.AnnotationViewFactory; +import lcsb.mapviewer.services.view.OverviewImageViewFactory; + +@Transactional(value = "txManager") +public class ElementsRestImpl extends BaseRestImpl { + + Logger logger = Logger.getLogger(ElementsRestImpl.class); + + @Autowired + private IModelService modelService; + + @Autowired + AnnotationViewFactory annotationViewFactory; + + @Autowired + private OverviewImageViewFactory factory; + + public List<Map<String, Object>> getElements(String projectId, String id, String columns, String modelId, String token) + throws UserAccessException, SecurityException { + Set<Integer> ids = new HashSet<>(); + if (!id.equals("")) { + for (String str : id.split(",")) { + ids.add(Integer.valueOf(str)); + } + } + Set<String> columnsSet = createElementColumnSet(columns); + + List<Map<String, Object>> result = new ArrayList<>(); + + List<Model> models = getModels(projectId, modelId, token); + + for (Model model2 : models) { + for (Element element : model2.getElements()) { + if (ids.size() == 0 || ids.contains(element.getId())) { + result.add(preparedElement(element, columnsSet)); + } + } + } + + return result; + } + + private Map<String, Object> preparedElement(Element element, Set<String> columnsSet) { + Map<String, Object> result = new HashMap<>(); + for (String string : columnsSet) { + String column = string.toLowerCase(); + Object value = null; + if (column.equals("id") || column.equals("idobject")) { + value = element.getId(); + } else if (column.equals("modelid")) { + value = element.getModelData().getId(); + } else if (column.equals("name")) { + value = element.getName(); + } else if (column.equals("type")) { + value = element.getStringType(); + } else if (column.equals("symbol")) { + value = element.getSymbol(); + } else if (column.equals("fullname")) { + value = element.getFullName(); + } else if (column.equals("abbreviation")) { + value = element.getAbbreviation(); + } else if (column.equals("compartmentid")) { + if (element.getCompartment() != null) { + value = element.getCompartment().getId(); + } + } else if (column.equals("complexid")) { + if (element instanceof Species) { + if (((Species) element).getComplex() != null) { + value = ((Species) element).getComplex().getId(); + } + } + } else if (column.equals("references")) { + value = annotationViewFactory.createList(element.getMiriamData()); + } else if (column.equals("synonyms")) { + value = element.getSynonyms(); + } else if (column.equals("formula")) { + value = element.getFormula(); + } else if (column.equals("description")) { + value = element.getNotes(); + } else if (column.equals("formersymbols")) { + value = element.getFormerSymbols(); + } else if (column.equals("hierarchyvisibilitylevel")) { + value = element.getVisibilityLevel(); + } else if (column.equals("bounds")) { + value = createBounds(element.getX(), element.getY(), element.getWidth(), element.getHeight()); + } else { + value = "Unknown column"; + } + result.put(string, value); + } + return result; + } + + private Map<String, Object> createBounds(Double x, Double y, Double width, Double height) { + Map<String, Object> result = new HashMap<>(); + result.put("x", x); + result.put("y", y); + result.put("width", width); + result.put("height", height); + return result; + } + + private Set<String> createElementColumnSet(String columns) { + Set<String> columnsSet = new HashSet<>(); + if (columns.equals("")) { + columnsSet.add("id"); + columnsSet.add("modelId"); + columnsSet.add("name"); + columnsSet.add("type"); + columnsSet.add("description"); + columnsSet.add("type"); + columnsSet.add("symbol"); + columnsSet.add("complexId"); + columnsSet.add("compartmentId"); + columnsSet.add("fullName"); + columnsSet.add("abbreviation"); + columnsSet.add("formula"); + columnsSet.add("name"); + columnsSet.add("synonyms"); + columnsSet.add("formerSymbols"); + columnsSet.add("references"); + columnsSet.add("bounds"); + columnsSet.add("hierarchyVisibilityLevel"); + } else { + for (String str : columns.split(",")) { + columnsSet.add(str); + } + } + return columnsSet; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + + /** + * @return the factory + * @see #factory + */ + public OverviewImageViewFactory getFactory() { + return factory; + } + + /** + * @param factory + * the factory to set + * @see #factory + */ + public void setFactory(OverviewImageViewFactory factory) { + this.factory = factory; + } +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java new file mode 100644 index 0000000000000000000000000000000000000000..2cde3d273df2dbf6fc40f1f3e383bb14efc5e4f5 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java @@ -0,0 +1,37 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.reactions; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class ReactionsController extends BaseController { + @Autowired + private ReactionsRestImpl reactionController; + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/reactions/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getReactions(// + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @RequestParam(value = "id", defaultValue = "") String id, // + @RequestParam(value = "columns", defaultValue = "") String columns, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @RequestParam(value = "participantId", defaultValue = "") String participantId// + ) throws SecurityException { + return reactionController.getReactions(projectId, id, columns, modelId, token, participantId); + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..c1305c14372b227c0cbbe080b7237a8ffc2152d3 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java @@ -0,0 +1,189 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.reactions; + +import java.awt.geom.PathIterator; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.reaction.Modifier; +import lcsb.mapviewer.model.map.reaction.Product; +import lcsb.mapviewer.model.map.reaction.Reactant; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.UserAccessException; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.search.data.LightReactionView; +import lcsb.mapviewer.services.view.AnnotationViewFactory; + +@Transactional(value = "txManager") +public class ReactionsRestImpl extends BaseRestImpl { + + Logger logger = Logger.getLogger(ReactionsRestImpl.class); + + @Autowired + private IUserService userService; + + @Autowired + private IModelService modelService; + + @Autowired + AnnotationViewFactory annotationViewFactory; + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + public List<Map<String, Object>> getReactions(String projectId, String id, String columns, String modelId, String token, String participantElementId) + throws UserAccessException, SecurityException { + Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token)); + Set<Integer> ids = new HashSet<>(); + if (!id.equals("")) { + for (String str : id.split(",")) { + ids.add(Integer.valueOf(str)); + } + } + Set<Element> elementSet = new HashSet<>(); + if (!participantElementId.equals("")) { + for (String str : participantElementId.split(",")) { + elementSet.add(model.getElementByDbId(Integer.valueOf(str))); + } + } + Set<String> columnsSet = createReactionColumnSet(columns); + + List<Map<String, Object>> result = new ArrayList<>(); + + List<Model> models = getModels(projectId, modelId, token); + + for (Model model2 : models) { + for (Reaction reaction : model2.getReactions()) { + if (ids.size() == 0 || ids.contains(reaction.getId())) { + if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) { + result.add(preparedReaction(reaction, columnsSet)); + } + } + } + } + + return result; + } + + private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) { + for (Element element : elementSet) { + if (reaction.containsElement(element)) { + return true; + } + } + return false; + } + + private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) { + Map<String, Object> result = new HashMap<>(); + for (String string : columnsSet) { + String column = string.toLowerCase(); + Object value = null; + if (column.equals("id") || column.equals("idobject")) { + value = reaction.getId(); + } else if (column.equals("modelid")) { + value = reaction.getModelData().getId(); + } else if (column.equals("reactionid")) { + value = reaction.getIdReaction(); + } else if (column.equals("name")) { + value = reaction.getName(); + } else if (column.equals("centerpoint")) { + value = reaction.getCenterPoint(); + } else if (column.equals("products")) { + List<Integer> ids = new ArrayList<>(); + for (Product product : reaction.getProducts()) { + ids.add(product.getElement().getId()); + } + value = StringUtils.join(ids, ","); + } else if (column.equals("reactants")) { + List<Integer> ids = new ArrayList<>(); + for (Reactant reactant : reaction.getReactants()) { + ids.add(reactant.getElement().getId()); + } + value = StringUtils.join(ids, ","); + } else if (column.equals("modifiers")) { + List<Integer> ids = new ArrayList<>(); + for (Modifier product : reaction.getModifiers()) { + ids.add(product.getElement().getId()); + } + value = StringUtils.join(ids, ","); + } else if (column.equals("type")) { + value = reaction.getStringType(); + } else if (column.equals("hierarchyvisibilitylevel")) { + value = reaction.getVisibilityLevel(); + } else if (column.equals("lines")) { + value = new LightReactionView(reaction).getLines(); + } else { + value = "Unknown column"; + } + result.put(string, value); + } + return result; + } + + private Set<String> createReactionColumnSet(String columns) { + Set<String> columnsSet = new HashSet<>(); + if (columns.equals("")) { + columnsSet.add("id"); + columnsSet.add("reactionId"); + columnsSet.add("modelId"); + columnsSet.add("type"); + columnsSet.add("lines"); + columnsSet.add("centerPoint"); + columnsSet.add("products"); + columnsSet.add("reactants"); + columnsSet.add("modifiers"); + columnsSet.add("hierarchyVisibilityLevel"); + } else { + for (String str : columns.split(",")) { + columnsSet.add(str); + } + } + return columnsSet; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsController.java new file mode 100644 index 0000000000000000000000000000000000000000..32a73f0d1532436b12752ffa35e94d2ccc7f0a5c --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsController.java @@ -0,0 +1,36 @@ +package lcsb.mapviewer.api.projects.models.publications; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; + +@RestController +public class PublicationsController extends BaseController { + @Autowired + private PublicationsRestImpl projectController; + + @RequestMapping(value = "/projects/{projectId}/models/{modelId}/publications/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getPublications(// + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @RequestParam(value = "start", defaultValue = "0") String start, // + @RequestParam(value = "length", defaultValue = "10") Integer length// + ) throws QueryException, SecurityException { + return projectController.getPublications(projectId, modelId, token, start, length); + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..a17deb36691a28a079d48478b158aaa848a707cc --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImpl.java @@ -0,0 +1,223 @@ +package lcsb.mapviewer.api.projects.models.publications; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.exception.InvalidStateException; +import lcsb.mapviewer.model.map.AnnotatedObject; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelData; +import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.interfaces.ILayoutService; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.interfaces.ISearchService; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; +import lcsb.mapviewer.services.view.AnnotationViewFactory; +import lcsb.mapviewer.services.view.AuthenticationToken; +import lcsb.mapviewer.services.view.OverviewImageViewFactory; + +@Transactional(value = "txManager") +public class PublicationsRestImpl extends BaseRestImpl{ + + Logger logger = Logger.getLogger(PublicationsRestImpl.class); + + @Autowired + private IUserService userService; + + @Autowired + private IModelService modelService; + + @Autowired + private ISearchService searchService; + + @Autowired + AnnotationViewFactory annotationViewFactory; + + @Autowired + private PubmedParser pubmedParser; + + @Autowired + private OverviewImageViewFactory factory; + + public SortedMap<MiriamData, List<AnnotatedObject>> getPublications(List<Model> models) { + SortedMap<MiriamData, List<AnnotatedObject>> publications = new TreeMap<>(); + for (Model modelData : models) { + for (Element element : modelData.getElements()) { + for (MiriamData md : element.getMiriamData()) { + if (md.getDataType().equals(MiriamType.PUBMED)) { + List<AnnotatedObject> list = publications.get(md); + if (list == null) { + list = new ArrayList<>(); + publications.put(md, list); + } + list.add(element); + } + } + } + for (Reaction reaction : modelData.getReactions()) { + for (MiriamData md : reaction.getMiriamData()) { + if (md.getDataType().equals(MiriamType.PUBMED)) { + List<AnnotatedObject> list = publications.get(md); + if (list == null) { + list = new ArrayList<>(); + publications.put(md, list); + } + list.add(reaction); + } + } + + } + } + return publications; + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + /** + * @return the modelService + * @see #modelService + */ + public IModelService getModelService() { + return modelService; + } + + /** + * @param modelService + * the modelService to set + * @see #modelService + */ + public void setModelService(IModelService modelService) { + this.modelService = modelService; + } + + /** + * @return the searchService + * @see #searchService + */ + public ISearchService getSearchService() { + return searchService; + } + + /** + * @param searchService + * the searchService to set + * @see #searchService + */ + public void setSearchService(ISearchService searchService) { + this.searchService = searchService; + } + + /** + * @return the factory + * @see #factory + */ + public OverviewImageViewFactory getFactory() { + return factory; + } + + /** + * @param factory + * the factory to set + * @see #factory + */ + public void setFactory(OverviewImageViewFactory factory) { + this.factory = factory; + } + + public Map<String, Object> getPublications(String projectId, String modelId, String token, String startString, Integer length) throws SecurityException, QueryException { + List<Model> models = getModels(projectId, modelId, token); + + Integer start = Math.max(0, Integer.valueOf(startString)); + List<Map<String, Object>> resultList = new ArrayList<>(); + + SortedMap<MiriamData, List<AnnotatedObject>> publications = getPublications(models); + int index = 0; + Set<String> columns = new HashSet<>(); + columns.add("id"); + columns.add("type"); + columns.add("modelid"); + for (Map.Entry<MiriamData, List<AnnotatedObject>> entry : publications.entrySet()) { + if (index >= start && index < start + length) { + List<Object> elements = new ArrayList<>(); + for (AnnotatedObject object : entry.getValue()) { + elements.add(createMinifiedSearchResult(object)); + } + + Map<String, Object> row = new HashMap<>(); + row.put("elements", elements); + if (entry.getKey().getDataType().equals(MiriamType.PUBMED)) { + try { + row.put("publication", pubmedParser.getPubmedArticleById(Integer.valueOf(entry.getKey().getResource()))); + } catch (Exception e) { + logger.error(e, e); + row.put("publication", annotationViewFactory.create(entry.getKey())); + } + } else { + row.put("publication", annotationViewFactory.create(entry.getKey())); + } + resultList.add(row); + } + index++; + + } + + Map<String, Object> result = new HashMap<>(); + result.put("data", resultList); + result.put("totalSize", publications.size()); + result.put("start", start); + result.put("length", resultList.size()); + return result; + } + + /** + * @return the pubmedParser + * @see #pubmedParser + */ + public PubmedParser getPubmedParser() { + return pubmedParser; + } + + /** + * @param pubmedParser + * the pubmedParser to set + * @see #pubmedParser + */ + public void setPubmedParser(PubmedParser pubmedParser) { + this.pubmedParser = pubmedParser; + } + +} diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayController.java new file mode 100644 index 0000000000000000000000000000000000000000..45a4ada00d1e377fb5074471b13441b6bf8ae353 --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayController.java @@ -0,0 +1,161 @@ +package lcsb.mapviewer.api.projects.overlays; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.model.cache.FileEntry; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.view.LayoutView; + +@RestController +public class OverlayController extends BaseController { + + private Logger logger = Logger.getLogger(OverlayController.class); + + @Autowired + private OverlayRestImpl overlayRestImp; + + @RequestMapping(value = "/projects/{projectId}/overlays/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<LayoutView> getOverlayList(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId // + ) throws SecurityException, QueryException { + return overlayRestImp.getOverlayList(token, projectId); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}/", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public LayoutView getOverlayById(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "overlayId") String overlayId// + ) throws SecurityException, QueryException { + return overlayRestImp.getOverlayById(token, projectId, overlayId); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public List<Map<String, Object>> getOverlayElements(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "overlayId") String overlayId, @RequestParam(value = "columns", defaultValue = "") String columns) + throws SecurityException, QueryException { + return overlayRestImp.getOverlayElements(token, projectId, Integer.valueOf(overlayId), columns); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/reactions/{reactionId}/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getFullReaction(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @PathVariable(value = "overlayId") String overlayId, // + @PathVariable(value = "reactionId") String reactionId, // + @RequestParam(value = "columns", defaultValue = "") String columns // + ) throws SecurityException, QueryException { + return overlayRestImp + .getOverlayElement(token, projectId, Integer.valueOf(modelId), Integer.valueOf(overlayId), Integer.valueOf(reactionId), "REACTION", columns); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}/models/{modelId}/bioEntities/elements/{elementId}/", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getFullSpecies(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "modelId") String modelId, // + @PathVariable(value = "overlayId") String overlayId, // + @PathVariable(value = "elementId") String reactionId, // + @RequestParam(value = "columns", defaultValue = "") String columns // + ) throws SecurityException, QueryException { + return overlayRestImp + .getOverlayElement(token, projectId, Integer.valueOf(modelId), Integer.valueOf(overlayId), Integer.valueOf(reactionId), "ALIAS", columns); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/", method = { RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public LayoutView addOverlay( // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @RequestParam(value = "name") String name, // + @RequestParam(value = "description") String description, // + @RequestParam(value = "content") String content, // + @RequestParam(value = "filename") String filename, // + @RequestParam(value = "type", defaultValue = "") String type // + ) throws SecurityException, QueryException, IOException { + return overlayRestImp.addOverlay(token, projectId, name, description, content, filename, type); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}", method = { RequestMethod.DELETE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> removeOverlay( // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "overlayId") String overlayId // + ) throws SecurityException, QueryException, IOException { + return overlayRestImp.removeOverlay(token, projectId, overlayId); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}", method = { RequestMethod.PATCH }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public LayoutView updateOverlay( // + @RequestBody String body, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "overlayId") String overlayId, // + @CookieValue(value = Configuration.AUTH_TOKEN) String token // + ) throws SecurityException, QueryException, IOException { + Map<String, Object> node = parseBody(body); + Map<String, Object> data = getData(node, "overlay"); + return overlayRestImp.updateOverlay(token, projectId, overlayId, data); + } + + @RequestMapping(value = "/projects/{projectId}/overlays/{overlayId}:downloadSource", method = { RequestMethod.GET }, + produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity<byte[]> getOverlaySource( // + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "projectId") String projectId, // + @PathVariable(value = "overlayId") String overlayId // + ) throws SecurityException, QueryException, JsonParseException, JsonMappingException, IOException { + + FileEntry file = overlayRestImp.getOverlaySource(token, projectId, overlayId); + MediaType type = MediaType.TEXT_PLAIN; + if (file.getOriginalFileName().endsWith("xml")) { + type = MediaType.APPLICATION_XML; + } + return ResponseEntity + .ok().contentLength(file.getFileContent().length).contentType(type).header("Content-Disposition", "attachment; filename=" + file.getOriginalFileName()) + .body(file.getFileContent()); + } + + /** + * @return the overlayRestImp + * @see #overlayRestImp + */ + public OverlayRestImpl getOverlayRestImp() { + return overlayRestImp; + } + + /** + * @param overlayRestImp + * the overlayRestImp to set + * @see #overlayRestImp + */ + public void setOverlayRestImp(OverlayRestImpl overlayRestImp) { + this.overlayRestImp = overlayRestImp; + } + +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java similarity index 78% rename from rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java index 5f931f7b60ee0951431a9ef3bef334b53c451d26..37e9665cee9eaad2ef5c390ddcf29eae87626da9 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/overlay/OverlayRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.overlay; +package lcsb.mapviewer.api.projects.overlays; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -14,12 +14,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import lcsb.mapviewer.api.BaseRestImpl; +import lcsb.mapviewer.api.ObjectNotFoundException; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.cache.FileEntry; import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; import lcsb.mapviewer.model.map.layout.Layout; import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.user.PrivilegeType; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.persist.dao.map.LayoutDao; import lcsb.mapviewer.services.SecurityException; @@ -29,6 +32,7 @@ import lcsb.mapviewer.services.interfaces.IModelService; import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType; import lcsb.mapviewer.services.search.layout.FullLayoutAliasView; +import lcsb.mapviewer.services.search.layout.FullLayoutReactionView; import lcsb.mapviewer.services.search.layout.LightLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutReactionView; import lcsb.mapviewer.services.utils.data.ColorSchemaType; @@ -167,45 +171,60 @@ public class OverlayRestImpl extends BaseRestImpl { } } - public Map<String, Object> updateOverlay(String token, String projectId, String overlayId, String name, String description) - throws QueryException, SecurityException { + public LayoutView updateOverlay(String token, String projectId, String overlayId, Map<String, Object> overlayData) throws QueryException, SecurityException { AuthenticationToken authenticationToken = userService.getToken(token); Model model = modelService.getLastModelByProjectId(projectId, authenticationToken); if (model == null) { throw new QueryException("Project with given id doesn't exist"); } + if (overlayData == null) { + throw new QueryException("overlay field cannot be undefined"); + } + Project project = model.getProject(); + boolean isAdmin = userService.userHasPrivilege(authenticationToken, PrivilegeType.LAYOUT_MANAGEMENT, project); try { Integer id = Integer.valueOf(overlayId); Layout layout = layoutService.getLayoutDataById(id, authenticationToken); if (layout == null) { - throw new QueryException("Invalid overlay id"); + throw new ObjectNotFoundException("overlay doesn't exist"); + } + if (layout.isPublicLayout() && !isAdmin) { + throw new SecurityException("You cannot modify given overlay"); + } + if (overlayData.containsKey("description")) { + layout.setDescription((String) overlayData.get("description")); + } + if (overlayData.containsKey("name")) { + layout.setTitle((String) overlayData.get("name")); } - layout.setDescription(description); - layout.setTitle(name); layoutDao.update(layout); } catch (NumberFormatException e) { - throw new QueryException("Invalid overlay id"); + throw new ObjectNotFoundException("overlay doesn't exist"); } - return okStatus(); + return layoutService.getLayoutById(model, Integer.valueOf(overlayId), authenticationToken); } public Map<String, Object> removeOverlay(String token, String projectId, String overlayId) throws QueryException, SecurityException, IOException { AuthenticationToken authenticationToken = userService.getToken(token); Model model = modelService.getLastModelByProjectId(projectId, authenticationToken); if (model == null) { - throw new QueryException("Project with given id doesn't exist"); + throw new ObjectNotFoundException("Project with given id doesn't exist"); } try { Integer id = Integer.valueOf(overlayId); LayoutView layout = layoutService.getLayoutById(model, id, authenticationToken); if (layout == null) { - throw new QueryException("Invalid overlay id"); + throw new ObjectNotFoundException("Overlay doesn't exist"); + } + if (layoutService.userCanRemoveLayout(layout, authenticationToken)) { + layoutService.removeLayout(layout, null); + return okStatus(); + } else { + throw new SecurityException("You cannot remove given overlay"); } - layoutService.removeLayout(layout, null); } catch (NumberFormatException e) { - throw new QueryException("Invalid overlay id"); + throw new QueryException("Invalid overlay id: " + overlayId); } - return okStatus(); } /** @@ -225,12 +244,12 @@ public class OverlayRestImpl extends BaseRestImpl { this.layoutDao = layoutDao; } - public Map<String, Object> addOverlay(String token, String projectId, String name, String description, String content, String filename, String type) + public LayoutView addOverlay(String token, String projectId, String name, String description, String content, String filename, String type) throws SecurityException, QueryException, IOException { AuthenticationToken authenticationToken = userService.getToken(token); User user = userService.getUserByToken(token); if (Configuration.ANONYMOUS_LOGIN.equals(user.getLogin())) { - throw new SecurityException("You have no privileges to add layout"); + throw new SecurityException("You have no privileges to add overlay"); } Model model = modelService.getLastModelByProjectId(projectId, authenticationToken); if (model == null) { @@ -253,25 +272,13 @@ public class OverlayRestImpl extends BaseRestImpl { new CreateLayoutParams() .async(false).colorInputStream(stream).description(description).layoutFileName(filename).model(model).name(name).user(user) .colorSchemaType(colorSchemaType).directory(".")); - Map<String, Object> result = okStatus(); - result.put("overlayId", layout.getIdObject()); - return result; + return layoutService.getLayoutById(model, Integer.valueOf(layout.getIdObject()), authenticationToken); } catch (InvalidColorSchemaException e) { throw new QueryException(e.getMessage(), e); } } - public List<Map<String, Object>> getOverlayTypes(String token) { - List<Map<String, Object>> result = new ArrayList<>(); - for (ColorSchemaType type : ColorSchemaType.values()) { - Map<String, Object> map = new HashMap<>(); - map.put("name", type.name()); - result.add(map); - } - return result; - } - public Map<String, Object> getOverlayElement(String token, String projectId, Integer modelId, Integer overlayId, Integer elementId, String elementType, String columns) throws QueryException, SecurityException { AuthenticationToken authenticationToken = userService.getToken(token); @@ -288,6 +295,11 @@ public class OverlayRestImpl extends BaseRestImpl { result.put("type", ElementIdentifierType.ALIAS); result.put("overlayContent", layoutAliasView); return result; + } else if (ElementIdentifierType.REACTION.getJsName().equals(elementType)) { + FullLayoutReactionView layoutAliasView = layoutService.getFullReactionForLayout(model, elementId, overlayId, authenticationToken); + result.put("type", ElementIdentifierType.REACTION); + result.put("overlayContent", layoutAliasView); + return result; } else { throw new QueryException("Unknown element type: " + elementType); } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java new file mode 100644 index 0000000000000000000000000000000000000000..175fd6325c0e97e11da201c05cb5d1c9acb2b4be --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserController.java @@ -0,0 +1,119 @@ +package lcsb.mapviewer.api.users; + +import java.io.IOException; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lcsb.mapviewer.api.BaseController; +import lcsb.mapviewer.api.ObjectNotFoundException; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.services.SecurityException; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.view.AuthenticationToken; + +@RestController +public class UserController extends BaseController { + Logger logger = Logger.getLogger(UserController.class); + + @Autowired + private IUserService userService; + + @Autowired + private UserRestImpl userRest; + + @RequestMapping(value = "/doLogin", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> login(// + @RequestParam(value = "login", defaultValue = Configuration.ANONYMOUS_LOGIN) String login, // + @RequestParam(value = "password", required = false) String password, // + HttpServletResponse response // + ) throws SecurityException, IOException { + AuthenticationToken token = userService.login(login, password); + if (token == null) { + throw new SecurityException("Invalid credentials"); + } else { + Map<String, Object> result = new HashMap<>(); + final Boolean useSecureCookie = false; + final int expiryTime = (int) (token.getExpires().getTimeInMillis() - Calendar.getInstance().getTimeInMillis()) / 1000; // 24h + // in + // seconds + final String cookiePath = "/"; + + Cookie cookie = new Cookie("MINERVA_AUTH_TOKEN", token.getId()); + + cookie.setSecure(useSecureCookie); + cookie.setMaxAge(expiryTime); + cookie.setPath(cookiePath); + + response.addCookie(cookie); + response.getWriter().write("{\"info\":\"Login successful. TOKEN returned as a cookie\"}"); + response.getWriter().flush(); + response.getWriter().close(); + return result; + } + } + + @RequestMapping(value = "/users/{login}", method = { RequestMethod.GET}, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, Object> getUser(// + @CookieValue(value = Configuration.AUTH_TOKEN) String token, // + @PathVariable(value = "login") String login, // + @RequestParam(value = "columns", defaultValue = "") String columns// + ) throws SecurityException, ObjectNotFoundException { + return userRest.getUser(token, login, columns); + } + + @RequestMapping(value = "/doLogout", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public Map<String, String> logout(@CookieValue(value = Configuration.AUTH_TOKEN) String token) throws SecurityException { + userService.logout(token); + Map<String, String> response = new HashMap<>(); + response.put("status", "OK"); + return response; + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + + /** + * @return the userRest + * @see #userRest + */ + public UserRestImpl getUserRest() { + return userRest; + } + + /** + * @param userRest + * the userRest to set + * @see #userRest + */ + public void setUserRest(UserRestImpl userRest) { + this.userRest = userRest; + } +} \ No newline at end of file diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java similarity index 88% rename from rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java rename to rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java index a6de82a583a845dce5a03f606753925d123b6a25..1aef78c3c4651cfd214cb0854984783a3ef8f0ce 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/controller/UserRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/users/UserRestImpl.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.controller; +package lcsb.mapviewer.api.users; import java.util.ArrayList; import java.util.HashMap; @@ -10,6 +10,7 @@ import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import lcsb.mapviewer.api.ObjectNotFoundException; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.model.user.BasicPrivilege; import lcsb.mapviewer.model.user.ObjectPrivilege; @@ -45,25 +46,19 @@ public class UserRestImpl { this.userService = userService; } - public Map<String, Object> getUser(String token, String userId, String columns) throws SecurityException { + public Map<String, Object> getUser(String token, String login, String columns) throws SecurityException, ObjectNotFoundException { User ownUserData = userService.getUserByToken(token); - Integer id = null; - if (userId != null && !userId.isEmpty()) { - id = Integer.valueOf(userId); - } else { - id = ownUserData.getId(); - } Set<String> columnSet = createUserColumnSet(columns); boolean isAdmin = userService.userHasPrivilege(ownUserData, PrivilegeType.USER_MANAGEMENT); - if (ownUserData.getId().equals(id)) { + if (ownUserData.getLogin().equals(login)) { return prepareUse(ownUserData, columnSet, true); } else if (isAdmin) { - User user = userService.getUserById(id); + User user = userService.getUserByLogin(login); if (user == null) { - throw new SecurityException("You cannot access data of the user with given id"); + throw new ObjectNotFoundException("User doesn't exist"); } return prepareUse(user, columnSet, isAdmin); } else { diff --git a/rest-api/src/main/resources/applicationContext-rest.xml b/rest-api/src/main/resources/applicationContext-rest.xml index f626936c6d2f1ca8795c5050f117d45ac09ff34b..5cbacb6fc6473c8ce69a2acb2117cc956ad83528 100644 --- a/rest-api/src/main/resources/applicationContext-rest.xml +++ b/rest-api/src/main/resources/applicationContext-rest.xml @@ -11,14 +11,20 @@ http://www.springframework.org/schema/context/spring-context.xsd"> - <bean id="ChemicalRestImpl" class="lcsb.mapviewer.api.chemical.ChemicalRestImpl"/> <bean id="ConfigurationRestImpl" class="lcsb.mapviewer.api.configuration.ConfigurationRestImpl"/> - <bean id="CommentRestImpl" class="lcsb.mapviewer.api.comment.CommentRestImpl"/> - <bean id="DrugRestImpl" class="lcsb.mapviewer.api.drug.DrugRestImpl"/> - <bean id="MiRnaRestImpl" class="lcsb.mapviewer.api.mirna.MiRnaRestImpl"/> - <bean id="OverlayRestImpl" class="lcsb.mapviewer.api.overlay.OverlayRestImpl"/> - <bean id="ProjectRestImpl" class="lcsb.mapviewer.api.project.ProjectRestImpl"/> + + <bean id="CommentRestImpl" class="lcsb.mapviewer.api.projects.comments.CommentRestImpl"/> + <bean id="ProjectRestImpl" class="lcsb.mapviewer.api.projects.ProjectRestImpl"/> + <bean id="BioEntitiesRestImpl" class="lcsb.mapviewer.api.projects.models.bioEntities.BioEntitiesRestImpl"/> + <bean id="ChemicalRestImpl" class="lcsb.mapviewer.api.projects.chemicals.ChemicalRestImpl"/> + <bean id="ElementsRestImpl" class="lcsb.mapviewer.api.projects.models.bioEntities.elements.ElementsRestImpl"/> + <bean id="DrugRestImpl" class="lcsb.mapviewer.api.projects.drugs.DrugRestImpl"/> + <bean id="MiRnaRestImpl" class="lcsb.mapviewer.api.projects.mirnas.MiRnaRestImpl"/> + <bean id="OverlayRestImpl" class="lcsb.mapviewer.api.projects.overlays.OverlayRestImpl"/> + <bean id="PublicationsRestImpl" class="lcsb.mapviewer.api.projects.models.publications.PublicationsRestImpl"/> + <bean id="ReactionsRestImpl" class="lcsb.mapviewer.api.projects.models.bioEntities.reactions.ReactionsRestImpl"/> + <bean id="ReferenceGenomeRestImpl" class="lcsb.mapviewer.api.genomics.ReferenceGenomeRestImpl"/> - <bean id="UserRestImpl" class="lcsb.mapviewer.api.controller.UserRestImpl"/> + <bean id="UserRestImpl" class="lcsb.mapviewer.api.users.UserRestImpl"/> </beans> \ No newline at end of file diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java index 8f77e99093e2c36f3be6b0e040410a666b408a97..24879c2e08e08808b2a6e520b1f35ddc178416ea 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/AllRestTests.java @@ -6,9 +6,9 @@ import org.junit.runners.Suite.SuiteClasses; import lcsb.mapviewer.api.comment.AllCommentTests; import lcsb.mapviewer.api.configuration.AllConfigurationTests; -import lcsb.mapviewer.api.controller.AllUserTests; import lcsb.mapviewer.api.genomics.AllGenomicsTests; -import lcsb.mapviewer.api.project.AllProjectTests; +import lcsb.mapviewer.api.projects.AllProjectTests; +import lcsb.mapviewer.api.users.AllUserTests; @RunWith(Suite.class) @SuiteClasses({ AllCommentTests.class, // diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/comment/CommentRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/comment/CommentRestImplTest.java index c37e1cc8455d77c9b935210f098f7faf874f5aff..9b8e8de34a6b386c7e91ad03d3a3372dca757886 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/comment/CommentRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/comment/CommentRestImplTest.java @@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.api.projects.comments.CommentRestImpl; public class CommentRestImplTest extends RestTestFunctions { diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java deleted file mode 100644 index 0453ff0272fbe24a3bb6757ceb917126556ea02c..0000000000000000000000000000000000000000 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/AllProjectTests.java +++ /dev/null @@ -1,12 +0,0 @@ -package lcsb.mapviewer.api.project; - -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.junit.runners.Suite.SuiteClasses; - -@RunWith(Suite.class) -@SuiteClasses({ ModelMetaDataTest.class,// - ProjectRestImplTest.class }) -public class AllProjectTests { - -} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/AllProjectTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/AllProjectTests.java new file mode 100644 index 0000000000000000000000000000000000000000..708c0ebd981846bc6815c97ec26d9ccff84ffa06 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/AllProjectTests.java @@ -0,0 +1,17 @@ +package lcsb.mapviewer.api.projects; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import lcsb.mapviewer.api.projects.models.AllModelsTests; +import lcsb.mapviewer.api.projects.overlays.AllOverlaysTests; + +@RunWith(Suite.class) +@SuiteClasses({ AllModelsTests.class, // + AllOverlaysTests.class, // + ModelMetaDataTest.class, // + ProjectRestImplTest.class }) +public class AllProjectTests { + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ModelMetaDataTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ModelMetaDataTest.java similarity index 86% rename from rest-api/src/test/java/lcsb/mapviewer/api/project/ModelMetaDataTest.java rename to rest-api/src/test/java/lcsb/mapviewer/api/projects/ModelMetaDataTest.java index 43810a12d4ed67042c2dfa44142beb06f660aaee..521d3701fe25873c35726f782374abdef87d39f8 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ModelMetaDataTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ModelMetaDataTest.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.project; +package lcsb.mapviewer.api.projects; import static org.junit.Assert.assertNotNull; @@ -9,6 +9,7 @@ import org.junit.Test; import com.google.gson.Gson; +import lcsb.mapviewer.api.projects.ModelMetaData; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelFullIndexed; diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java similarity index 64% rename from rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java rename to rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java index a0e03f4dc1ef624e9c62912ee3696a4f0490b4bb..4c04050f6e09b4517a9aa9422143177076cd78d9 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/project/ProjectRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java @@ -1,16 +1,10 @@ -package lcsb.mapviewer.api.project; +package lcsb.mapviewer.api.projects; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; -import java.awt.geom.Point2D; -import java.util.List; -import java.util.Map; - import org.apache.log4j.Logger; import org.junit.After; import org.junit.AfterClass; @@ -50,39 +44,6 @@ public class ProjectRestImplTest extends RestTestFunctions { public void tearDown() throws Exception { } - @Test - public void testGetElementsProcessAllColumns() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - for (Map<String, Object> element : projectRest.getElements("sample", "", "", token.getId())) { - for (String paramName : element.keySet()) { - Object val = element.get(paramName); - String paramValue = ""; - if (val != null) { - paramValue = val.toString(); - } - assertFalse("Improper handler for column name: " + paramName, paramValue.contains("Unknown column")); - } - } - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetClosestElementsByCoordinates() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - int count = 3; - List<Map<String, Object>> result = projectRest.getClosestElementsByCoordinates("sample", "0", token.getId(), new Point2D.Double(1, 2), count); - assertEquals(count, result.size()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - @Test public void testGetModelAsImage() throws Exception { try { @@ -178,28 +139,4 @@ public class ProjectRestImplTest extends RestTestFunctions { return _projectRestImpl; } - @Test - public void testPublications() throws Exception { - try { - ProjectRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); - Map<String, Object> result = projectRest.getPublications("sample", token.getId(), "0", 20); - assertEquals(1, result.get("totalSize")); - assertEquals(0, result.get("start")); - assertEquals(1, ((List<?>) result.get("data")).size()); - - result = projectRest.getPublications("sample", token.getId(), "1", 20); - assertEquals(1, result.get("totalSize")); - assertEquals(1, result.get("start")); - assertEquals(0, ((List<?>) result.get("data")).size()); - - result = projectRest.getPublications("sample", token.getId(), "0", 00); - assertEquals(1, result.get("totalSize")); - assertEquals(0, result.get("start")); - assertEquals(0, ((List<?>) result.get("data")).size()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - } diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/AllModelsTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/AllModelsTests.java new file mode 100644 index 0000000000000000000000000000000000000000..f89ba7fa4d53d265c8f1b116b26d7832ed327c2c --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/AllModelsTests.java @@ -0,0 +1,18 @@ +package lcsb.mapviewer.api.projects.models; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import lcsb.mapviewer.api.projects.models.bioEntities.AllBioeEntitiesTests; +import lcsb.mapviewer.api.projects.models.bioEntities.elements.AllElementsTests; +import lcsb.mapviewer.api.projects.models.publications.AllPublicationsTests; + +@RunWith(Suite.class) +@SuiteClasses({ // + AllBioeEntitiesTests.class, // + AllPublicationsTests.class// +}) +public class AllModelsTests { + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/AllBioeEntitiesTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/AllBioeEntitiesTests.java new file mode 100644 index 0000000000000000000000000000000000000000..48a870c00f8daae830fd7f788730562cda51e4e0 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/AllBioeEntitiesTests.java @@ -0,0 +1,16 @@ +package lcsb.mapviewer.api.projects.models.bioEntities; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import lcsb.mapviewer.api.projects.models.bioEntities.elements.AllElementsTests; + +@RunWith(Suite.class) +@SuiteClasses({ // + AllElementsTests.class, // + BioEntitiesControllerTest.class // +}) +public class AllBioeEntitiesTests { + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesControllerTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..50bec236b39243a7a2ca3bfcad34e76447051193 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/BioEntitiesControllerTest.java @@ -0,0 +1,70 @@ +package lcsb.mapviewer.api.projects.models.bioEntities; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; + +import java.awt.geom.Point2D; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.services.interfaces.IModelService; + +public class BioEntitiesControllerTest extends RestTestFunctions { + Logger logger = Logger.getLogger(BioEntitiesControllerTest.class); + + @Autowired + BioEntitiesRestImpl _bioEntitiesRestImpl; + + ObjectMapper mapper = new ObjectMapper(); + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetClosestElementsByCoordinates() throws Exception { + try { + BioEntitiesRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + int count = 3; + List<Map<String, Object>> result = projectRest.getClosestElementsByCoordinates("sample", "0", token.getId(), new Point2D.Double(1, 2), count, "false"); + assertEquals(count, result.size()); + + String json = mapper.writeValueAsString(result); + assertNotNull(json); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private BioEntitiesRestImpl createMockProjectRest(String string) throws Exception { + Model model = super.getModelForFile(string, true); + IModelService mockModelService = Mockito.mock(IModelService.class); + Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model); + _bioEntitiesRestImpl.setModelService(mockModelService); + return _bioEntitiesRestImpl; + } + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/AllElementsTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/AllElementsTests.java new file mode 100644 index 0000000000000000000000000000000000000000..90e36ec1ca8823ed9760d3d16b37b628ee8abb11 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/AllElementsTests.java @@ -0,0 +1,11 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.elements; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ ElementRestImplTest.class }) +public class AllElementsTests { + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementRestImplTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f3c30757319e0f2098957d09eb3da05e0b809b58 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementRestImplTest.java @@ -0,0 +1,75 @@ +package lcsb.mapviewer.api.projects.models.bioEntities.elements; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; + +import java.util.List; +import java.util.Map; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.services.interfaces.IModelService; + +public class ElementRestImplTest extends RestTestFunctions { + + @Autowired + ElementsRestImpl _elementsRestImpl; + + ObjectMapper mapper = new ObjectMapper(); + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetElementsProcessAllColumns() throws Exception { + try { + ElementsRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + List<Map<String, Object>> result = projectRest.getElements("sample", "", "", "*", token.getId()); + for (Map<String, Object> element : result) { + for (String paramName : element.keySet()) { + Object val = element.get(paramName); + String paramValue = ""; + if (val != null) { + paramValue = val.toString(); + } + assertFalse("Improper handler for column name: " + paramName, paramValue.contains("Unknown column")); + } + } + String json = mapper.writeValueAsString(result); + assertNotNull(json); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private ElementsRestImpl createMockProjectRest(String string) throws Exception { + Model model = super.getModelForFile(string, true); + IModelService mockModelService = Mockito.mock(IModelService.class); + Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model); + _elementsRestImpl.setModelService(mockModelService); + return _elementsRestImpl; + } + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/AllPublicationsTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/AllPublicationsTests.java new file mode 100644 index 0000000000000000000000000000000000000000..c19d01a1d7af60a8faf81724bdb5e69a27e3c0cc --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/AllPublicationsTests.java @@ -0,0 +1,11 @@ +package lcsb.mapviewer.api.projects.models.publications; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ PublicationsRestImplTest.class }) +public class AllPublicationsTests { + +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..e5d385ab34181400d54f451620520c362420db36 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/models/publications/PublicationsRestImplTest.java @@ -0,0 +1,72 @@ +package lcsb.mapviewer.api.projects.models.publications; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; + +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.services.interfaces.IModelService; + +public class PublicationsRestImplTest extends RestTestFunctions { + Logger logger = Logger.getLogger(PublicationsRestImplTest.class); + + @Autowired + PublicationsRestImpl _projectRestImpl; + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testPublications() throws Exception { + try { + PublicationsRestImpl projectRest = createMockProjectRest("testFiles/model/sample.xml"); + Map<String, Object> result = projectRest.getPublications("sample", "*", token.getId(), "0", 20); + assertEquals(1, result.get("totalSize")); + assertEquals(0, result.get("start")); + assertEquals(1, ((List<?>) result.get("data")).size()); + + result = projectRest.getPublications("sample", "*", token.getId(), "1", 20); + assertEquals(1, result.get("totalSize")); + assertEquals(1, result.get("start")); + assertEquals(0, ((List<?>) result.get("data")).size()); + + result = projectRest.getPublications("sample", "*", token.getId(), "0", 00); + assertEquals(1, result.get("totalSize")); + assertEquals(0, result.get("start")); + assertEquals(0, ((List<?>) result.get("data")).size()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + private PublicationsRestImpl createMockProjectRest(String string) throws Exception { + Model model = super.getModelForFile(string, true); + IModelService mockModelService = Mockito.mock(IModelService.class); + Mockito.when(mockModelService.getLastModelByProjectId(anyString(), any())).thenReturn(model); + _projectRestImpl.setModelService(mockModelService); + return _projectRestImpl; + } + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/overlays/AllOverlaysTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/overlays/AllOverlaysTests.java new file mode 100644 index 0000000000000000000000000000000000000000..daf60c8088672175d23a5947536c5a6f62a42f8d --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/overlays/AllOverlaysTests.java @@ -0,0 +1,11 @@ +package lcsb.mapviewer.api.projects.overlays; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ }) +public class AllOverlaysTests { + +} diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/users/AllUserTests.java similarity index 80% rename from rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java rename to rest-api/src/test/java/lcsb/mapviewer/api/users/AllUserTests.java index 85b6fdea54c67a4c7bf35cedc4a52e7fecfd05db..992680c3019f85c30c38334498fc947e37cd2166 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/controller/AllUserTests.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/users/AllUserTests.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.controller; +package lcsb.mapviewer.api.users; import org.junit.runner.RunWith; import org.junit.runners.Suite; diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java similarity index 87% rename from rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java rename to rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java index 4d4096cdf350aa5271c800cc40a3a84c201eb2d9..bf0a293174ca78f4fe43c3908c5a341f3d88d530 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/controller/UserRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/users/UserRestImplTest.java @@ -1,4 +1,4 @@ -package lcsb.mapviewer.api.controller; +package lcsb.mapviewer.api.users; import static org.junit.Assert.assertNotNull; @@ -10,6 +10,7 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import lcsb.mapviewer.api.RestTestFunctions; +import lcsb.mapviewer.api.users.UserRestImpl; public class UserRestImplTest extends RestTestFunctions { Logger logger = Logger.getLogger(UserRestImplTest.class); diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java index 08d1314773be8b3f220302fdf91f2ed7b0044e9f..d1b2df719b2095c1424414e012dd19b1af3183d7 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java @@ -60,6 +60,8 @@ import lcsb.mapviewer.services.interfaces.ILogService.LogParams; import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.search.layout.FullLayoutAliasView; import lcsb.mapviewer.services.search.layout.FullLayoutAliasViewFactory; +import lcsb.mapviewer.services.search.layout.FullLayoutReactionView; +import lcsb.mapviewer.services.search.layout.FullLayoutReactionViewFactory; import lcsb.mapviewer.services.search.layout.LightLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutAliasViewFactory; import lcsb.mapviewer.services.search.layout.LightLayoutReactionView; @@ -1075,4 +1077,36 @@ public class LayoutService implements ILayoutService { throw new InvalidStateException(e); } } + + @Override + public FullLayoutReactionView getFullReactionForLayout(Model model, Integer id, int layoutId, AuthenticationToken token) throws SecurityException { + try { + ColorSchemaReader reader = new ColorSchemaReader(); + Collection<ColorSchema> schemas; + schemas = reader.readColorSchema(getInputDataForLayout(layoutId, token)); + // colors here are not important + ColorModelCommand command = new ColorModelCommand(model, schemas, new ColorExtractor(Color.BLACK, Color.BLACK)); + FullLayoutReactionViewFactory factory = new FullLayoutReactionViewFactory(); + + for (Map.Entry<Object, ColorSchema> entry : command.getModifiedElements().entrySet()) { + if (entry.getKey() instanceof Reaction) { + Reaction alias = (Reaction) entry.getKey(); + if (id.equals(alias.getId())) { + return factory.create(new Pair<Reaction, ColorSchema>(alias, entry.getValue())); + } + } + } + return null; + } catch (InvalidColorSchemaException e) { + throw new InvalidStateException(e); + } catch (IOException e) { + throw new InvalidStateException(e); + } + } + + @Override + public boolean userCanRemoveLayout(LayoutView layout, AuthenticationToken authenticationToken) { + User user = userService.getUserByToken(authenticationToken); + return userCanRemoveLayout(layout, user); + } } diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java index c17dc5ebcd01a44d69052c6d937ea307a5093840..666eda198cad493fb2e11b7be74d37d8aea4409d 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java @@ -136,11 +136,6 @@ public class ReferenceGenomeService implements IReferenceGenomeService { public ReferenceGenomeView getReferenceGenomeViewByParams(MiriamData miriamData, ReferenceGenomeType genomeType, String version) { List<ReferenceGenome> list = referenceGenomeDao.getByType(genomeType); for (ReferenceGenome referenceGenome : list) { - logger.debug(referenceGenome.getOrganism()); - logger.debug(referenceGenome.getVersion()); - logger.debug("---"); - logger.debug(miriamData); - logger.debug(version); if (referenceGenome.getOrganism().equals(miriamData) && referenceGenome.getVersion().equals(version)) { return factory.create(referenceGenome); } diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java b/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java index 5020536b56da2bd99e24463d210effedf3f9121d..947a3d32991a6e0c51c83535987c72923b18b4da 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/SearchService.java @@ -527,7 +527,7 @@ public class SearchService implements ISearchService { } @Override - public List<Object> getClosestElements(Model model, Point2D point, int numberOfElements) { + public List<Object> getClosestElements(Model model, Point2D point, int numberOfElements, boolean perfectHit) { List<Object> result = new ArrayList<>(); // probably this could be improved algorithmitically, right now all objects @@ -545,7 +545,11 @@ public class SearchService implements ISearchService { Collections.sort(tmpList); int size = Math.min(tmpList.size(), numberOfElements); for (int i = 0; i < size; i++) { - result.add(tmpList.get(i).getReference()); + if (!perfectHit) { + result.add(tmpList.get(i).getReference()); + } else if (tmpList.get(i).getDistance() < Configuration.EPSILON) { + result.add(tmpList.get(i).getReference()); + } } return result; } diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java index f5a1b1ca8c20d253922b6659f76035cddc590bd5..cec9c0ac8c19ff86c1892ca31d24366196f28801 100644 --- a/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java +++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java @@ -16,6 +16,7 @@ import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.search.layout.FullLayoutAliasView; +import lcsb.mapviewer.services.search.layout.FullLayoutReactionView; import lcsb.mapviewer.services.search.layout.LightLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutReactionView; import lcsb.mapviewer.services.utils.EmailSender; @@ -502,6 +503,8 @@ public interface ILayoutService { throws SecurityException; FullLayoutAliasView getFullAliasForLayout(Model model, Integer id, int layoutId, AuthenticationToken token) throws SecurityException; + + FullLayoutReactionView getFullReactionForLayout(Model model, Integer id, int layoutId, AuthenticationToken token) throws SecurityException; /** * Returns {@link EmailSender} used by the service. @@ -524,4 +527,6 @@ public interface ILayoutService { Layout getLayoutDataById(int overlayId, AuthenticationToken authenticationToken) throws SecurityException; + boolean userCanRemoveLayout(LayoutView layout, AuthenticationToken authenticationToken); + } diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/ISearchService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/ISearchService.java index 3801640516d876b6b3d94cf72a0f9a3566b7d6b0..c7f51a65f43b178ba00c4eed1258cdaf3938bc4f 100644 --- a/service/src/main/java/lcsb/mapviewer/services/interfaces/ISearchService.java +++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/ISearchService.java @@ -295,7 +295,7 @@ public interface ISearchService { * how many closest elements should be returned * @return list of the closest elements */ - List<Object> getClosestElements(Model model, Point2D point, int numberOfElements); + List<Object> getClosestElements(Model model, Point2D point, int numberOfElements, boolean perfectHit); /** * Returns list of autocomplete strings for the partial query. diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionView.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionView.java new file mode 100644 index 0000000000000000000000000000000000000000..126b8493872e024db5b495721ead6b687423e119 --- /dev/null +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionView.java @@ -0,0 +1,15 @@ +package lcsb.mapviewer.services.search.layout; + +import lcsb.mapviewer.model.map.reaction.Reaction; + +public class FullLayoutReactionView extends LightLayoutReactionView { + + public FullLayoutReactionView(Reaction reaction) { + super(reaction); + } + + /** + * + */ + private static final long serialVersionUID = 1L; +} diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionViewFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..de40e6e11aef70a289ca1b9a97baea9ccbe008ed --- /dev/null +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutReactionViewFactory.java @@ -0,0 +1,39 @@ +package lcsb.mapviewer.services.search.layout; + +import org.apache.log4j.Logger; + +import com.google.gson.Gson; + +import lcsb.mapviewer.common.Pair; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.services.search.ElementViewFactory; + +/** + * Factory class for {@link LightLayoutReactionView} class. + * + * @author Piotr Gawron + * + */ +public class FullLayoutReactionViewFactory extends ElementViewFactory<Pair<Reaction, ColorSchema>, FullLayoutReactionView> { + /** + * Default class logger. + */ + @SuppressWarnings("unused") + private static Logger logger = Logger.getLogger(FullLayoutReactionViewFactory.class); + + @Override + public FullLayoutReactionView create(Pair<Reaction, ColorSchema> pair) { + FullLayoutReactionView result = new FullLayoutReactionView(pair.getLeft()); + result.setColor(pair.getRight().getColor()); + result.setValue(pair.getRight().getValue()); + result.setWidth(pair.getRight().getLineWidth()); + result.setReverse(pair.getRight().getReverseReaction()); + return result; + } + + @Override + public String createGson(FullLayoutReactionView object) { + return new Gson().toJson(object); + } +} diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/gmap/CoordinationConverter.java b/service/src/main/java/lcsb/mapviewer/services/utils/gmap/CoordinationConverter.java index f85c360f66e4335c49568c9328c30e19e2f380d9..235ac84cce3ef00bd871e0e416c2b3dd4b0273eb 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/gmap/CoordinationConverter.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/gmap/CoordinationConverter.java @@ -79,6 +79,10 @@ public final class CoordinationConverter implements Serializable { */ private final Point2D pixelOrigin; + private Double width; + + private Double height; + /** * Bounds value in the optMin, optMax range. * @@ -124,6 +128,8 @@ public final class CoordinationConverter implements Serializable { pixelOrigin = new Point2D.Double(tileSize / 2, tileSize / 2); pixelsPerLonDegree = tileSize / FULL_ANGLE_IN_DEGREES; pixelsPerLonRadian = tileSize / (2 * Math.PI); + width = model.getWidth(); + height = model.getHeight(); } /** @@ -176,7 +182,6 @@ public final class CoordinationConverter implements Serializable { * @return polygon in absolute coordinates */ public Path2D latLngToPolygon(String latLngPolygon) { - Path2D result = new Path2D.Double(); String[] latLngArray = latLngPolygon.split(";"); List<Point2D> points = new ArrayList<>(); @@ -192,8 +197,13 @@ public final class CoordinationConverter implements Serializable { } } if (points.size() <= 2) { - throw new InvalidArgumentException("Invalid polygon string. It should contain at least 3 points, but found: " + latLngPolygon); + points.clear(); + points.add(new Point2D.Double(0, 0)); + points.add(new Point2D.Double(width, 0)); + points.add(new Point2D.Double(width, height)); + points.add(new Point2D.Double(0, height)); } + Path2D result = new Path2D.Double(); result.moveTo(points.get(0).getX(), points.get(0).getY()); for (int i = 1; i < points.size(); i++) { Point2D point = points.get(i); diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/SearchServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/SearchServiceTest.java index 5e7afaf6357abab75d2343da1aa93c2734514194..571ef6105b32936e8d38fdcabce39d4d96cfe470 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/SearchServiceTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/SearchServiceTest.java @@ -231,7 +231,7 @@ public class SearchServiceTest extends ServiceTestFunctions { public void testSearchClosest() throws Exception { try { model = getModelForFile("testFiles/graph_path_example3.xml", true); - List<Object> elements = searchService.getClosestElements(model, new Point2D.Double(0, 0), 5); + List<Object> elements = searchService.getClosestElements(model, new Point2D.Double(0, 0), 5, false); assertNotNull(elements); assertEquals(5, elements.size()); assertTrue(elements.get(0) instanceof Species); @@ -260,7 +260,7 @@ public class SearchServiceTest extends ServiceTestFunctions { public void testSearchClosestWithEmptyModel() throws Exception { try { model = new ModelFullIndexed(null); - List<Object> elements = searchService.getClosestElements(model, new Point2D.Double(0, 0), 5); + List<Object> elements = searchService.getClosestElements(model, new Point2D.Double(0, 0), 5, false); assertNotNull(elements); assertEquals(0, elements.size()); diff --git a/web/.classpath b/web/.classpath index 81c8c83bbd22a3a107f7068c9ed97960a7af3a03..6acf3eeecaebe2d096ef46a44bf6988db916e316 100644 --- a/web/.classpath +++ b/web/.classpath @@ -1,37 +1,37 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" output="target/classes" path="src/main/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="output" path="target/classes"/> -</classpath> +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src/main/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="src" output="target/test-classes" path="src/test/java"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/web/.settings/org.eclipse.wst.common.component b/web/.settings/org.eclipse.wst.common.component index a9fabcecdb0c0b815bab4bf75df22678f54f1218..a43617e524ad51c00cc84611bdbf4122d9a5e86f 100644 --- a/web/.settings/org.eclipse.wst.common.component +++ b/web/.settings/org.eclipse.wst.common.component @@ -41,6 +41,6 @@ <dependency-type>uses</dependency-type> </dependent-module> <property name="java-output-path" value="/MapViewer-web/target/classes"/> - <property name="context-root" value="MapViewer-web"/> + <property name="context-root" value="web"/> </wb-module> </project-modules>