From 1858f8f9ae15f273278e93b4381be12dcea4d442 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 10 Nov 2017 15:46:30 +0100 Subject: [PATCH] overlays are uploaded in chunks (so big files can be uploaded as well) --- frontend-js/.idea/codeStyleSettings.xml | 29 +- frontend-js/.idea/frontend-js.iml | 2 +- frontend-js/package-lock.json | 5 + frontend-js/package.json | 3 +- frontend-js/src/main/js/ServerConnector.js | 3475 ++++++++--------- .../src/main/js/gui/AddOverlayDialog.js | 41 +- frontend-js/src/main/js/map/OverlayParser.js | 4 + .../src/test/js/ServerConnector-test.js | 2 +- .../src/test/js/map/OverlayParser-test.js | 13 + .../POST_token=MOCK_TOKEN_ID& | 7 + ...=unknown.txt&length=3&token=MOCK_TOKEN_ID& | 7 + ... => POST_fileId=6792&token=MOCK_TOKEN_ID&} | 0 .../projects/overlays/OverlayController.java | 274 +- .../projects/overlays/OverlayRestImpl.java | 33 +- .../api/projects/ProjectRestImplTest.java | 2 +- 15 files changed, 1999 insertions(+), 1898 deletions(-) create mode 100644 frontend-js/testFiles/apiCalls/files/6792.uploadContent/POST_token=MOCK_TOKEN_ID& create mode 100644 frontend-js/testFiles/apiCalls/files/POST_filename=unknown.txt&length=3&token=MOCK_TOKEN_ID& rename frontend-js/testFiles/apiCalls/projects/sample/overlays/{POST_content=s1%0A&token=MOCK_TOKEN_ID& => POST_fileId=6792&token=MOCK_TOKEN_ID&} (100%) diff --git a/frontend-js/.idea/codeStyleSettings.xml b/frontend-js/.idea/codeStyleSettings.xml index 2f2668eaed..a086a7b3cc 100644 --- a/frontend-js/.idea/codeStyleSettings.xml +++ b/frontend-js/.idea/codeStyleSettings.xml @@ -2,8 +2,33 @@ <project version="4"> <component name="ProjectCodeStyleSettingsManager"> <option name="PER_PROJECT_SETTINGS"> - <value /> + <value> + <DBN-PSQL> + <case-options enabled="false"> + <option name="KEYWORD_CASE" value="lower" /> + <option name="FUNCTION_CASE" value="lower" /> + <option name="PARAMETER_CASE" value="lower" /> + <option name="DATATYPE_CASE" value="lower" /> + <option name="OBJECT_CASE" value="preserve" /> + </case-options> + <formatting-settings enabled="false" /> + </DBN-PSQL> + <DBN-SQL> + <case-options enabled="false"> + <option name="KEYWORD_CASE" value="lower" /> + <option name="FUNCTION_CASE" value="lower" /> + <option name="PARAMETER_CASE" value="lower" /> + <option name="DATATYPE_CASE" value="lower" /> + <option name="OBJECT_CASE" value="preserve" /> + </case-options> + <formatting-settings enabled="false"> + <option name="STATEMENT_SPACING" value="one_line" /> + <option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" /> + <option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" /> + </formatting-settings> + </DBN-SQL> + </value> </option> - <option name="PREFERRED_PROJECT_CODE_STYLE" value="custom" /> + <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> </component> </project> \ No newline at end of file diff --git a/frontend-js/.idea/frontend-js.iml b/frontend-js/.idea/frontend-js.iml index 26f5495ad6..5964ef5d96 100644 --- a/frontend-js/.idea/frontend-js.iml +++ b/frontend-js/.idea/frontend-js.iml @@ -8,9 +8,9 @@ <excludeFolder url="file://$MODULE_DIR$/dist" /> <excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/temp" /> - <excludeFolder url="file://$MODULE_DIR$/testFiles" /> <excludeFolder url="file://$MODULE_DIR$/tmp" /> </content> + <content url="file://$MODULE_DIR$/testFiles/apiCalls" /> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="library" name="chai-DefinitelyTyped" level="application" /> diff --git a/frontend-js/package-lock.json b/frontend-js/package-lock.json index 1a472aa161..f036ef8b1e 100644 --- a/frontend-js/package-lock.json +++ b/frontend-js/package-lock.json @@ -3124,6 +3124,11 @@ "acorn": "4.0.13" } }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", diff --git a/frontend-js/package.json b/frontend-js/package.json index d042631c54..9dcf2e6e8c 100644 --- a/frontend-js/package.json +++ b/frontend-js/package.json @@ -47,6 +47,7 @@ "log4js": "0.6.38", "pileup": "^0.6.8", "request": "^2.82.0", - "spectrum-colorpicker": "^1.8.0" + "spectrum-colorpicker": "^1.8.0", + "text-encoding": "^0.6.4" } } diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 97e626f517..70199b541d 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -1,1738 +1,1737 @@ -"use strict"; - -/* exported logger */ - -var Promise = require("bluebird"); - -var logger = require('./logger'); - -var request = require('request'); - -var HttpStatus = require('http-status-codes'); - -var Alias = require('./map/data/Alias'); -var Annotation = require('./map/data/Annotation'); -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'); -var InvalidCredentialsError = require('./InvalidCredentialsError'); -var LayoutAlias = require('./map/data/LayoutAlias'); -var LayoutData = require('./map/data/LayoutData'); -var LayoutReaction = require('./map/data/LayoutReaction'); -var MapModel = require('./map/data/MapModel'); -var MiRna = require('./map/data/MiRna'); -var NetworkError = require('./NetworkError'); -var Project = require('./map/data/Project'); -var ProjectStatistics = require('./map/data/ProjectStatistics'); -var Reaction = require('./map/data/Reaction'); -var ReferenceGenome = require('./map/data/ReferenceGenome'); -var SecurityError = require('./SecurityError'); -var SessionData = require('./SessionData'); -var User = require('./map/data/User'); - -var GuiConnector = require('./GuiConnector'); - -var ObjectWithListeners = require('./ObjectWithListeners'); - -/** - * This object contains methods that will communicate with server. - */ -var ServerConnector = new ObjectWithListeners(); -ServerConnector.init = function () { - var self = this; - - self._configurationParam = []; - self._projects = []; - self._projectsById = []; - - self._users = []; - self._usersByLogin = []; - - self._customMap = null; - self._sessionData = undefined; - self._configuration = undefined; - self._loggedUser = undefined; - self._serverBaseUrl = undefined; - - var i; - var listeners = self.getListeners("onDataLoadStart"); - for (i = 0; i < listeners.length; i++) { - self.removeListener("onDataLoadStart", listeners[i]); - } - - listeners = self.getListeners("onDataLoadStop"); - for (i = 0; i < listeners.length; i++) { - self.removeListener("onDataLoadStop", listeners[i]); - } - -}; -ServerConnector.registerListenerType("onDataLoadStart"); -ServerConnector.registerListenerType("onDataLoadStop"); -ServerConnector.init(); - -ServerConnector.getMinOverlayColorInt = function () { - var self = this; - return self.getLoggedUser().then(function (user) { - var userColor = user.getMinColor(); - return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.MIN_COLOR_VAL)); - }); -}; - -ServerConnector.returnUserOrSystemColor = function (userColor, systemPromisedColor) { - return systemPromisedColor.then(function (systemColor) { - var color = userColor; - if (userColor === null || userColor === undefined || userColor === "") { - color = systemColor; - } - color = parseInt(color, 16); - /* jslint bitwise: true */ - color = (color & 0xFFFFFF); - return color; - }); -}; - -ServerConnector.getSimpleOverlayColorInt = function () { - var self = this; - return self.getLoggedUser().then(function (user) { - var userColor = user.getSimpleColor(); - return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.SIMPLE_COLOR_VAL)); - }); -}; - -ServerConnector.getMaxOverlayColorInt = function () { - var self = this; - return self.getLoggedUser().then(function (user) { - var userColor = user.getMaxColor(); - return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.MAX_COLOR_VAL)); - }); -}; - -ServerConnector.sendGetRequest = function (url, description) { - return this.sendRequest({ - url: url, - description: description, - method: "GET" - }); -}; - -ServerConnector.sendRequest = function (params) { - var self = this; - if (arguments.length > 1) { - return Promise.reject(new Error("Only two arguments are supported")); - } - - if (self.getSessionData().getToken() === undefined) { - self.getSessionData().setLogin(undefined); - window.location.reload(false); - } - - var description = params.url; - if (params.description !== undefined) { - description = params.description; - params.description = undefined; - } - - var content; - return self.callListeners("onDataLoadStart", description).then(function () { - return self._sendRequest(params); - }).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; - }); - -}; - -ServerConnector._sendRequest = function (params) { - return new Promise(function (resolve, reject) { - request(params, function (error, response, body) { - if (error) { - reject(new NetworkError(error.message, { - content: body, - url: params.url - })); - } else if (response.statusCode !== 200) { - reject(new NetworkError(params.url + " rejected with status code: " + response.statusCode, { - content: body, - url: params.url, - statusCode: response.statusCode - })); - } else { - // for some reason sometimes result is an object not a string - if (typeof body === 'string' || body instanceof String) { - resolve(body); - } else { - resolve(JSON.stringify(body)); - } - } - }); - }); -}; - -ServerConnector.sendPostRequest = function (url, params) { - return this.sendRequest({ - method: "POST", - url: url, - form: params - }); -}; - -ServerConnector.sendDeleteRequest = function (url, json) { - return this.sendRequest({ - method: "DELETE", - url: url, - json: json - }); -}; - -ServerConnector.sendPatchRequest = function (url, json) { - return this.sendRequest({ - method: "PATCH", - url: url, - json: json - }); -}; - -ServerConnector.getToken = function () { - var self = this; - - var login = self.getSessionData(null).getLogin(); - var token = self.getSessionData(null).getToken(); - if (token === undefined || login === 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.getConfiguration().then(function () { - return token; - // if there was an error accessing configuration it means our token is - // invalid - }, function () { - return self.login(); - }); - } else { - return Promise.resolve(token); - } - } -}; - -ServerConnector.getApiBaseUrl = function () { - return this.getServerBaseUrl() + "/api/"; -}; - -ServerConnector.getServerBaseUrl = function () { - if (this._serverBaseUrl === undefined) { - var url = "" + window.location.href; - if (url.indexOf("?") >= 0) { - url = url.substr(0, url.indexOf("?")); - } - if (!url.endsWith("/")) { - url = url.substr(0, url.lastIndexOf("/") + 1); - } - this._serverBaseUrl = url; - } - return this._serverBaseUrl; -}; - -ServerConnector.createGetParams = function (params, prefix) { - var sorted = [], key; - - for (key in params) { - if (params.hasOwnProperty(key)) { - sorted.push(key); - } - } - sorted.sort(); - - var result = ""; - for (var i = 0; i < sorted.length; 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; -}; - -ServerConnector.getApiUrl = function (paramObj) { - var type = paramObj.type; - var params = this.createGetParams(paramObj.params); - - var result = paramObj.url; - if (result === undefined) { - result = this.getApiBaseUrl() + "/" + type; - } - if (params !== "") { - result += "?" + params; - } - return result; -}; - -ServerConnector.getProjectsUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - type: "projects/", - params: filterParams - }); -}; - -ServerConnector.getProjectUrl = function (queryParams, filterParams) { - var id = this.getIdOrAsterisk(queryParams.projectId); - return this.getApiUrl({ - url: this.getProjectsUrl(queryParams) + id + "/", - params: filterParams - }); -}; - -ServerConnector.getProjectStatisticsUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "statistics/", - params: filterParams - }); -}; - -ServerConnector.getPublicationsUrl = function (queryParams, filterParams) { - filterParams.start = filterParams.start || 0; - filterParams.length = filterParams.length || 10; - - return this.getApiUrl({ - url: this.getModelsUrl(queryParams) + "publications/", - params: filterParams - }); -}; -ServerConnector.getProjectLogsUrl = function (queryParams, filterParams) { - filterParams.start = filterParams.start || 0; - filterParams.length = filterParams.length || 10; - - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "logs/", - params: filterParams - }); -}; - - -ServerConnector.getReferenceGenomeUrl = function (queryParams, filterParams) { - var version = this.getIdOrAsterisk(queryParams.version); - - return this.getApiUrl({ - type: "genomics/taxonomies/" + queryParams.organism + "/genomeTypes/" + queryParams.type + "/versions/" + version - + "/", - params: filterParams - }); -}; - -ServerConnector.loginUrl = function () { - return this.getApiUrl({ - type: "/doLogin" - }); -}; - -ServerConnector.logoutUrl = function () { - return this.getApiUrl({ - type: "/doLogout" - }); -}; - -ServerConnector.getSuggestedQueryListUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getBioEntitiesUrl(queryParams) + "suggestedQueryList/", - params: filterParams - }); -}; - -ServerConnector.addCommentUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getCommentsUrl(queryParams) - }); -}; - -ServerConnector.addOverlayUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getOverlaysUrl(queryParams) - }); -}; - -ServerConnector.updateOverlayUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getOverlayByIdUrl(queryParams) - }); -}; - -ServerConnector.deleteOverlayUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getOverlayByIdUrl(queryParams) - }); -}; - -ServerConnector.deleteCommentUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "comments/" + queryParams.commentId + "/" - }); -}; - -ServerConnector.getOverlaysUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "overlays/", - params: filterParams - }); -}; - -ServerConnector.getCommentsUrl = function (queryParams, filterParams) { - var modelId = this.getIdOrAsterisk(queryParams.modelId); - var url = this.getProjectUrl(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({ - url: url, - params: filterParams - }); -}; - -ServerConnector.getOverlayByIdUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getOverlaysUrl(queryParams) + queryParams.overlayId + "/", - params: filterParams - }); - -}; - -ServerConnector.getOverlayElementsUrl = function (queryParams, filterParams) { - - return this.getApiUrl({ - url: this.getModelsUrl(queryParams) + "bioEntities/", - params: filterParams - }); - -}; - -ServerConnector.getFullOverlayElementUrl = function (queryParams, filterParams) { - - return this.getApiUrl({ - url: this.getAliasesUrl(queryParams) + queryParams.id + "/", - params: filterParams - }); - -}; - -ServerConnector.idsToString = function (ids) { - var result = ""; - if (ids !== undefined) { - ids.sort(function (a, b) { - if (typeof a === "string") { - return a.localeCompare(b); - } else { - return a - b; - } - }); - for (var i = 0; i < ids.length; i++) { - if (result !== "") { - if (ids[i - 1] !== ids[i]) { - result = result + "," + ids[i]; - } // we ignore duplicates - } else { - result = ids[i]; - } - } - } - return result; -}; - -ServerConnector.pointToString = function (point) { - return point.x.toFixed(2) + "," + point.y.toFixed(2); -}; - -ServerConnector.getModelsUrl = function (queryParams) { - var modelId = this.getIdOrAsterisk(queryParams.modelId); - var overlayId = queryParams.overlayId; - var url = this.getProjectUrl(queryParams); - if (overlayId !== undefined) { - url = this.getOverlayByIdUrl(queryParams); - } - - return this.getApiUrl({ - url: url + "models/" + modelId + "/" - }); -}; - -ServerConnector.getBioEntitiesUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getModelsUrl(queryParams) + "bioEntities/" - }); -}; - -ServerConnector.getIdOrAsterisk = function (id) { - if (id === undefined || id === "" || id === null) { - return "*"; - } else { - return id; - } -}; - -ServerConnector.getReactionsUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getBioEntitiesUrl(queryParams) + "reactions/", - params: filterParams - }); -}; - -ServerConnector.getAliasesUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getBioEntitiesUrl(queryParams) + "elements/", - params: filterParams - }); -}; - -ServerConnector.getConfigurationUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - type: "configuration/", - params: filterParams - }); -}; - -ServerConnector.getConfigurationOptionUrl = function (queryParams, filterParams) { - var self = this; - return self.getApiUrl({ - url: self.getConfigurationUrl() + "options/" + queryParams.type, - params: filterParams - }); -}; - - -ServerConnector.getSearchUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getModelsUrl(queryParams) + "bioEntities:search", - params: filterParams - }); -}; - -ServerConnector.getSearchDrugsUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "drugs:search", - params: filterParams - }); -}; - -ServerConnector.getSearchMiRnasUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "miRnas:search", - params: filterParams - }); -}; - -ServerConnector.getSearchChemicalsUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "chemicals:search", - params: filterParams - }); -}; - -ServerConnector.getOverlaySourceUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getOverlaysUrl(queryParams) + queryParams.overlayId + ":downloadSource", - params: filterParams - }); -}; - -ServerConnector.getImageUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "models/" + queryParams.modelId + ":downloadImage", - params: filterParams - }); -}; - -ServerConnector.getModelPartUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getProjectUrl(queryParams) + "models/" + queryParams.modelId + ":downloadModel", - params: filterParams - }); -}; - -ServerConnector.getProjectSourceUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - type: "projects/" + queryParams.projectId + ":downloadSource", - params: filterParams - }); -}; - - -ServerConnector.getFilesUrl = function () { - return this.getApiUrl({ - type: "files/" - }); -}; - -ServerConnector.getCreateFileUrl = function () { - return this.getApiUrl({ - url: this.getFilesUrl() - }); -}; -ServerConnector.getFileUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getFilesUrl() + "/" + queryParams.id - }); -}; -ServerConnector.getUploadFileUrl = function (queryParams) { - return this.getApiUrl({ - url: this.getFileUrl(queryParams) + ":uploadContent" - }); -}; - - -ServerConnector.getUsersUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - type: "users/", - params: filterParams - }); -}; - -ServerConnector.getUserUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getUsersUrl() + queryParams.login, - params: filterParams - }); -}; - -ServerConnector.getUpdateUserPrivilegesUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getUserUrl(queryParams) + ":updatePrivileges", - params: filterParams - }); -}; -ServerConnector.getUpdateUserPreferencesUrl = function (queryParams, filterParams) { - return this.getApiUrl({ - url: this.getUserUrl(queryParams) + ":updatePreferences", - params: filterParams - }); -}; - -ServerConnector.getConfiguration = function () { - var self = this; - if (this._configuration === undefined) { - return self.sendGetRequest(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) { - if (paramId === undefined) { - return Promise.reject(new Error("Unknown param type")); - } - var self = this; - return self.getConfiguration().then(function (configuration) { - var option = configuration.getOption(paramId); - if (option.getValue !== undefined) { - return option.getValue(); - } else { - return option; - } - }); -}; -ServerConnector.updateConfigurationOption = function (option) { - var self = this; - var queryParams = { - type: option.getType() - }; - var filterParams = { - option: { - type: option.getType(), - value: option.getValue() - } - }; - return self.sendPatchRequest(self.getConfigurationOptionUrl(queryParams), filterParams); -}; - -ServerConnector.getModels = function (projectId) { - var queryParams = {}; - var filterParams = {}; - var self = this; - return self.getProjectId(projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getModelsUrl(queryParams, filterParams)); - }).then(function (content) { - var models = []; - var parsedJson = JSON.parse(content); - for (var i = 0; i < parsedJson.length; i++) { - models.push(new MapModel(parsedJson[i])); - } - return models; - }); -}; - -ServerConnector.getProject = function (projectId) { - var queryParams = {}; - var filterParams = {}; - var project; - var self = this; - return self.getProjectId(projectId).then(function (result) { - projectId = result; - queryParams.projectId = result; - return self.sendGetRequest(self.getProjectUrl(queryParams, filterParams)); - }).then(function (content) { - var downloadedProject = new Project(content); - if (self._projectsById[projectId] !== undefined) { - self._projectsById[projectId].update(downloadedProject); - } else { - self._projectsById[projectId] = downloadedProject; - } - project = self._projectsById[projectId]; - return self.getModels(projectId); - }).then(function (models) { - project.setModel(models[0]); - return self.getLoggedUser(); - }).then(function (user) { - return self.getOverlays({ - projectId: projectId, - creator: user.getLogin(), - publicOverlay: false - }); - }).then(function (overlays) { - if (project.getModel() !== undefined) { - project.getModel().addLayouts(overlays); - } else { - if (overlays.length > 0) { - logger.warn("Cannot add overlays to the project: " + project.getProjectId()); - } - } - return project; - }).then(null, function (error) { - if ((error instanceof NetworkError)) { - switch (error.statusCode) { - case HttpStatus.NOT_FOUND: - return null; - case HttpStatus.FORBIDDEN: - return Promise.reject(new SecurityError("Access denied.")); - default: - return Promise.reject(error); - } - } else { - return Promise.reject(error); - } - }); -}; - -ServerConnector.updateProject = function (project) { - var self = this; - var queryParams = { - projectId: project.getProjectId() - }; - var filterParams = { - project: { - name: project.getName(), - version: project.getVersion(), - notifyEmail: project.getNotifyEmail(), - organism: self.serialize(project.getOrganism()), - disease: self.serialize(project.getDisease()) - } - }; - return self.sendPatchRequest(self.getProjectUrl(queryParams), filterParams).then(function (content) { - var downloadedProject = new Project(content); - project.update(downloadedProject); - return project; - }).then(null, function (error) { - if ((error instanceof NetworkError)) { - switch (error.statusCode) { - case HttpStatus.FORBIDDEN: - return Promise.reject(new SecurityError("Access denied.")); - default: - return Promise.reject(error); - } - } else { - return Promise.reject(error); - } - }); -}; - -ServerConnector.removeProject = function (projectId) { - var self = this; - var queryParams = { - projectId: projectId - }; - return self.sendDeleteRequest(self.getProjectUrl(queryParams)).then(function (content) { - var project = new Project(content); - if (self._projectsById[project.getProjectId()] !== undefined) { - self._projectsById[project.getProjectId()].update(project); - } else { - self._projectsById[project.getProjectId()] = project; - } - return self._projectsById[project.getProjectId()]; - }).then(null, function (error) { - if ((error instanceof NetworkError)) { - switch (error.statusCode) { - case HttpStatus.FORBIDDEN: - return Promise.reject(new SecurityError("Access denied.")); - default: - return Promise.reject(error); - } - } else { - return Promise.reject(error); - } - }); -}; - -ServerConnector.addProject = function (options) { - var self = this; - var queryParams = { - projectId: options.projectId - }; - return self.sendPostRequest(self.getProjectUrl(queryParams), options).then(function (content) { - var project = new Project(content); - if (self._projectsById[project.getProjectId()] !== undefined) { - self._projectsById[project.getProjectId()].update(project); - } else { - self._projectsById[project.getProjectId()] = project; - } - return project; - }).then(null, function (error) { - if ((error instanceof NetworkError)) { - switch (error.statusCode) { - case HttpStatus.FORBIDDEN: - return Promise.reject(new SecurityError("Access denied.")); - default: - return Promise.reject(error); - } - } else { - return Promise.reject(error); - } - }); -}; - -ServerConnector.serialize = function (object) { - var result = {}; - if (object instanceof Annotation) { - result.type = object.getType(); - result.resource = object.getResource(); - } else { - throw new Error("Unhandled object type: " + (typeof object)); - } - return result; -}; - -ServerConnector.getProjects = function (reload) { - var self = this; - if (self._projects.length > 0 && !reload) { - return Promise.resolve(self._projects); - } else { - return self.sendGetRequest(self.getProjectsUrl()).then(function (content) { - var parsedData = JSON.parse(content); - self._projects.length = 0; - for (var i = 0; i < parsedData.length; i++) { - var project = new Project(JSON.stringify(parsedData[i])); - if (self._projectsById[project.getProjectId()] !== undefined) { - self._projectsById[project.getProjectId()].update(project); - } else { - self._projectsById[project.getProjectId()] = project; - } - self._projects.push(self._projectsById[project.getProjectId()]); - } - return self._projects; - }); - } -}; - -ServerConnector.getProjectStatistics = function (projectId) { - var queryParams = {}; - var filterParams = {}; - var self = this; - var content; - return self.getProjectId(projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getProjectStatisticsUrl(queryParams, filterParams)); - }).then(function (result) { - content = JSON.parse(result); - return self.getConfiguration(); - }).then(function (configuration) { - return new ProjectStatistics(content, configuration); - }); -}; - -ServerConnector.getLoggedUser = function () { - var self = this; - if (self._loggedUser !== undefined) { - return Promise.resolve(self._loggedUser); - } else { - return self.getUser(self.getSessionData().getLogin()).then(function (user) { - self._loggedUser = user; - return self._loggedUser; - }); - } -}; - -ServerConnector.getUser = function (login) { - var self = this; - var queryParams = { - login: login - }; - var filterParams = {}; - - return self.sendGetRequest(self.getUserUrl(queryParams, filterParams)).then(function (content) { - var obj = JSON.parse(content); - var user = new User(obj); - if (self._usersByLogin[user.getLogin()] !== undefined) { - self._usersByLogin[user.getLogin()].update(user); - } else { - self._usersByLogin[user.getLogin()] = user; - } - return self._usersByLogin[user.getLogin()]; - }).then(null, function (error) { - return self.processNetworkError(error); - }); -}; - -ServerConnector.updateUser = function (user) { - var self = this; - var queryParams = { - login: user.getLogin() - }; - var filterParams = { - user: { - name: user.getName(), - surname: user.getSurname(), - password: user.getPassword(), - email: user.getEmail() - } - }; - return self.sendPatchRequest(self.getUserUrl(queryParams), filterParams).then(function () { - return self.getConfiguration(); - }).then(function (configuration) { - return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); - }); - -}; -ServerConnector.addUser = function (user) { - var self = this; - var queryParams = { - login: user.getLogin() - }; - var filterParams = { - login: user.getLogin(), - name: user.getName(), - surname: user.getSurname(), - password: user.getPassword(), - email: user.getEmail() - }; - return self.sendPostRequest(self.getUserUrl(queryParams), filterParams).then(function () { - return self.getConfiguration(); - }).then(function (configuration) { - return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); - }); - -}; - -ServerConnector.removeUser = function (login) { - var self = this; - var queryParams = { - login: login - }; - return self.sendDeleteRequest(self.getUserUrl(queryParams)); - -}; - -ServerConnector.updateUserPrivileges = function (params) { - var self = this; - var queryParams = { - login: params.user.getLogin() - }; - - return self.sendPatchRequest(self.getUpdateUserPrivilegesUrl(queryParams), { - privileges: params.privileges - }).then(function (content) { - var obj = JSON.parse(content); - var user = new User(obj); - if (self._usersByLogin[user.getLogin()] !== undefined) { - self._usersByLogin[user.getLogin()].update(user); - } else { - self._usersByLogin[user.getLogin()] = user; - } - return self._usersByLogin[user.getLogin()]; - }).then(null, function (error) { - return self.processNetworkError(error); - }); -}; - -ServerConnector.processNetworkError = function (error) { - if ((error instanceof NetworkError)) { - switch (error.statusCode) { - case HttpStatus.NOT_FOUND: - return null; - case HttpStatus.FORBIDDEN: - return Promise.reject(new SecurityError("Access denied.")); - default: - return Promise.reject(error); - } - } else { - return Promise.reject(error); - } -}; - - -ServerConnector.updateUserPreferences = function (params) { - var self = this; - var queryParams = { - login: params.user.getLogin() - }; - - return self.sendPatchRequest(self.getUpdateUserPreferencesUrl(queryParams), { - preferences: params.preferences.toExport() - }).then(function (content) { - var obj = JSON.parse(content); - var user = new User(obj); - if (self._usersByLogin[user.getLogin()] !== undefined) { - self._usersByLogin[user.getLogin()].update(user); - } else { - self._usersByLogin[user.getLogin()] = user; - } - return self._usersByLogin[user.getLogin()]; - }); -}; - -ServerConnector.getUsers = function (forceRefresh) { - var self = this; - - if (self._users.length > 0 && !forceRefresh) { - return Promise.resolve(self._users); - } else { - return self.sendGetRequest(self.getUsersUrl()).then(function (content) { - var parsedData = JSON.parse(content); - self._users.length = 0; - for (var i = 0; i < parsedData.length; i++) { - var user = new User(parsedData[i]); - if (self._usersByLogin[user.getLogin()] !== undefined) { - self._usersByLogin[user.getLogin()].update(user); - } else { - self._usersByLogin[user.getLogin()] = user; - } - self._users.push(self._usersByLogin[user.getLogin()]); - } - return self._users; - }); - } - -}; - -ServerConnector.getOverlays = function (params) { - var self = this; - if (params === undefined) { - params = {}; - } - var queryParams = {}; - var filterParams = { - creator: params.creator, - publicOverlay: params.publicOverlay - }; - return new Promise(function (resolve, reject) { - self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getOverlaysUrl(queryParams, filterParams)); - }).then(function (content) { - var arr = JSON.parse(content); - var result = []; - for (var i = 0; i < arr.length; i++) { - var overlay = new LayoutData(arr[i]); - result.push(overlay); - } - resolve(result); - }, reject); - }); -}; - -ServerConnector.getOverlayElements = function (overlayId, projectId) { - var self = this; - if (overlayId === undefined) { - throw new Error("Layout id must be defined"); - } - var queryParams = { - overlayId: overlayId, - modelId: "*" - }; - var filterParams = {}; - return self.getProjectId(projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getOverlayElementsUrl(queryParams, filterParams)); - }).then(function (content) { - var arr = JSON.parse(content); - var result = []; - for (var i = 0; i < arr.length; i++) { - var element = arr[i]; - if (element.type === "REACTION") { - result.push(new LayoutReaction(element.overlayContent)); - } else if (element.type === "ALIAS") { - result.push(new LayoutAlias(element.overlayContent)); - } else { - throw new Error("Unknown element type: " + element.type); - } - } - return result; - }); -}; - -ServerConnector.getFullOverlayElement = function (params) { - var self = this; - - 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.sendGetRequest(self.getFullOverlayElementUrl(queryParams, filterParams)); - }).then(function (content) { - var element = JSON.parse(content); - var result = null; - if (element.type === "REACTION") { - result = new LayoutReaction(element.overlayContent); - } else if (element.type === "ALIAS") { - result = new LayoutAlias(element.overlayContent); - } else { - throw new Error("Unknown element type: " + element.type); - } - return result; - }); -}; - -ServerConnector.getProjectId = function (projectId) { - var self = this; - if (projectId !== undefined && projectId !== null && projectId !== "") { - return Promise.resolve(projectId); - } else if (GuiConnector.getParams['id'] !== undefined) { - return Promise.resolve(GuiConnector.getParams['id']); - } else { - return self.getConfigurationParam(ConfigurationType.DEFAULT_MAP); - } -}; - -ServerConnector.getLogoImg = function () { - return this.getConfigurationParam(ConfigurationType.LOGO_IMG); -}; - -ServerConnector.getLogoLink = function () { - return this.getConfigurationParam(ConfigurationType.LOGO_LINK); -}; - -ServerConnector.getMaxSearchDistance = function () { - return this.getConfigurationParam(ConfigurationType.SEARCH_DISTANCE); -}; - -ServerConnector.getOverlayById = function (overlayId, projectId) { - var self = this; - var queryParams = { - overlayId: overlayId - }; - var filterParams = {}; - return self.getProjectId(projectId).then(function (data) { - queryParams.projectId = data; - return self.sendGetRequest(self.getOverlayByIdUrl(queryParams, filterParams)); - }).then(function (content) { - return new LayoutData(JSON.parse(content)); - }); -}; - -ServerConnector.getReactions = function (params) { - var self = this; - var queryParams = {}; - if (params.ids === undefined) { - params.ids = []; - } - if (params.participantId === undefined) { - params.participantId = []; - } - var filterParams = { - id: params.ids, - columns: params.columns, - participantId: params.participantId, - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - if (filterParams.id.length > 100 || filterParams.participantId.length > 100) { - return self.sendPostRequest(self.getReactionsUrl(queryParams), filterParams); - } else { - return self.sendGetRequest(self.getReactionsUrl(queryParams, filterParams)); - } - - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new Reaction(array[i])); - } - return result; - }); -}; - -ServerConnector.getAliases = function (params) { - var self = this; - var queryParams = { - modelId: params.modelId - }; - if (params.ids === undefined) { - params.ids = []; - } - if (params.includedCompartmentIds === undefined) { - params.includedCompartmentIds = []; - } - if (params.excludedCompartmentIds === undefined) { - params.excludedCompartmentIds = []; - } - var filterParams = { - id: params.ids, - columns: params.columns, - type: params.type, - excludedCompartmentIds: params.excludedCompartmentIds, - includedCompartmentIds: params.includedCompartmentIds - - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - if (filterParams.id.length > 100) { - return self.sendPostRequest(self.getAliasesUrl(queryParams), filterParams); - } else { - return self.sendGetRequest(self.getAliasesUrl(queryParams, filterParams)); - } - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new Alias(array[i])); - } - return result; - }); -}; - -ServerConnector.getLightComments = function (params) { - params.columns = ["id", "elementId", "modelId", "type", "icon", "removed", "pinned"]; - return this.getComments(params); -}; - -ServerConnector.getComments = function (params) { - var self = this; - var queryParams = { - elementId: params.elementId, - elementType: params.elementType, - coordinates: params.coordinates - }; - var filterParams = { - columns: params.columns - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getCommentsUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new Comment(array[i])); - } - return result; - }); -}; - -ServerConnector.getSessionData = function (project) { - if (this._sessionData === undefined) { - this._sessionData = new SessionData(project); - } - if (project !== undefined && this._sessionData.getProject() === null) { - this._sessionData.setProject(project); - } - return this._sessionData; -}; - -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) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new IdentifiedElement(array[i])); - } - return result; - }); -}; - -ServerConnector.login = function (login, password) { - var self = this; - var params = {}; - if (login !== undefined && login !== "") { - params.login = login; - params.password = password; - } else { - params.login = "anonymous"; - } - self.getSessionData().setToken(""); - return self.sendPostRequest(self.loginUrl(), params).then(function () { - self.getSessionData().setLogin(params.login); - return Promise.resolve(self.getSessionData().getToken()); - }, function (error) { - if (error instanceof NetworkError && error.statusCode === HttpStatus.FORBIDDEN) { - throw new InvalidCredentialsError("Invalid credentials"); - } else { - throw error; - } - }); -}; - -ServerConnector.logout = function () { - var self = this; - self.getSessionData().setToken(undefined); - self.getSessionData().setLogin(undefined); - return self.sendGetRequest(self.logoutUrl()); -}; - -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) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new IdentifiedElement(array[i])); - } - return result; - }); -}; - -ServerConnector.getDrugsByQuery = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - query: params.query - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchDrugsUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new Drug(array[i])); - } - return result; - }); -}; - -ServerConnector.getMiRnasByQuery = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - query: params.query - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchMiRnasUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new MiRna(array[i])); - } - return result; - }); -}; - -ServerConnector.getChemicalsByQuery = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - query: params.query - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchChemicalsUrl(queryParams, filterParams)); - }).then(function (content) { - var array = JSON.parse(content); - var result = []; - for (var i = 0; i < array.length; i++) { - result.push(new Chemical(array[i])); - } - return result; - }); -}; - -ServerConnector.getOverlaySourceDownloadUrl = function (params) { - var self = this; - var queryParams = { - overlayId: params.overlayId - }; - var filterParams = {}; - return self.getProjectId(params.projectId).then(function (result) { - 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) { - 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) { - queryParams.projectId = result; - return self.getModelPartUrl(queryParams, filterParams); - }); -}; - -ServerConnector.getImageConverters = function () { - var self = this; - return self.getConfiguration().then(function (configuration) { - return configuration.getImageConverters(); - }); -}; -ServerConnector.getModelConverters = function () { - var self = this; - return self.getConfiguration().then(function (configuration) { - return configuration.getModelConverters(); - }); -}; - -ServerConnector.getProjectSourceDownloadUrl = function (params) { - if (params === undefined) { - params = {}; - } - var queryParams = {}; - var filterParams = {}; - var self = this; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.getProjectSourceUrl(queryParams, filterParams); - }); -}; - -ServerConnector.getDrugNamesByTarget = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - columns: ["name"], - target: params.target.getType() + ":" + params.target.getId() - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchDrugsUrl(queryParams, filterParams)); - }).then(function (content) { - var result = []; - var object = JSON.parse(content); - for (var i = 0; i < object.length; i++) { - result.push(object[i].name); - } - return result; - }); -}; - -ServerConnector.getMiRnaNamesByTarget = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - columns: ["name"], - target: params.target.getType() + ":" + params.target.getId() - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchMiRnasUrl(queryParams, filterParams)); - }).then(function (content) { - var result = []; - var object = JSON.parse(content); - for (var i = 0; i < object.length; i++) { - result.push(object[i].name); - } - return result; - }); -}; - -ServerConnector.getChemicalNamesByTarget = function (params) { - var self = this; - var queryParams = {}; - var filterParams = { - columns: ["name"], - target: params.target.getType() + ":" + params.target.getId() - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getSearchChemicalsUrl(queryParams, filterParams)); - }).then(function (content) { - var result = []; - var object = JSON.parse(content); - for (var i = 0; i < object.length; i++) { - result.push(object[i].name); - } - return result; - }); -}; - -ServerConnector.addComment = function (params) { - var self = this; - 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 overlay = params.overlay; - if (!(overlay instanceof LayoutData)) { - throw new Error("Invalid overlay: " + overlay); - } - var self = this; - var queryParams = {}; - var data = { - name: overlay.getName(), - description: overlay.getDescription(), - content: overlay.getContent(), - filename: overlay.getFilename() - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendPostRequest(self.addOverlayUrl(queryParams), data); - }).then(function (content) { - return new LayoutData(JSON.parse(content)); - }); -}; - -ServerConnector.updateOverlay = function (overlay) { - var self = this; - var queryParams = { - overlayId: overlay.getId() - }; - var filterParams = { - overlay: { - name: overlay.getName(), - description: overlay.getDescription(), - creator: overlay.getCreator(), - publicOverlay: overlay.getPublicOverlay() - } - }; - return self.sendPatchRequest(self.updateOverlayUrl(queryParams), filterParams); -}; - -ServerConnector.removeOverlay = function (params) { - var self = this; - 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); - }); -}; - -ServerConnector.removeComment = function (params) { - var self = this; - var queryParams = { - commentId: params.commentId - }; - var filterParams = {}; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendDeleteRequest(self.deleteCommentUrl(queryParams), filterParams); - }); -}; - -ServerConnector.getSuggestedQueryList = function (projectId) { - var self = this; - return self.getProjectId(projectId).then(function (result) { - projectId = result; - return self.sendGetRequest(self.getSuggestedQueryListUrl({ - projectId: projectId - })); - }).then(function (content) { - return JSON.parse(content); - }); -}; - -ServerConnector.getOverlayTypes = function () { - var self = this; - return self.getConfiguration().then(function (configuration) { - return configuration.getOverlayTypes(); - }); -}; - -ServerConnector.getPublications = function (params) { - var self = this; - if (params === undefined) { - params = {}; - } - - var queryParams = {}; - var filterParams = { - start: params.start, - length: params.length, - sortColumn: params.sortColumn, - sortOrder: params.sortOrder, - search: params.search - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getPublicationsUrl(queryParams, filterParams)); - }).then(function (content) { - return JSON.parse(content); - }); -}; - -ServerConnector.getReferenceGenome = function (params) { - var self = this; - var filterParams = {}; - return self.sendGetRequest(self.getReferenceGenomeUrl(params, filterParams)).then(function (content) { - return new ReferenceGenome(JSON.parse(content)); - }); -}; - -ServerConnector.uploadFile = function (params) { - var CHUNK_SIZE = 65535; - var self = this; - var data = new Uint8Array(params.content); - var filterParams = { - filename: params.filename, - length: data.length - }; - - return self.sendPostRequest(self.getCreateFileUrl(), filterParams).then(function (response) { - var uploadedLength = 0; - var createPromise = function (resultFileJson) { - var resultFile = JSON.parse(resultFileJson); - if (uploadedLength >= data.length) { - return Promise.resolve(resultFile); - } else { - var chunk = data.slice(uploadedLength, uploadedLength + CHUNK_SIZE); - logger.debug("SEND " + chunk.length + " bytes"); - var url = self.getUploadFileUrl({id: resultFile.id}); - return self.sendRequest({method: "POST", url: url, body: chunk}).then(function (resultFileJson) { - uploadedLength += chunk.length; - logger.debug("RESPONSE ", resultFileJson); - return createPromise(resultFileJson); - }) - } - }; - return createPromise(response); - }); -}; - - -ServerConnector.getProjectLogs = function (params) { - var self = this; - if (params === undefined) { - params = {}; - } - - var queryParams = {}; - var filterParams = { - start: params.start, - length: params.length, - sortColumn: params.sortColumn, - sortOrder: params.sortOrder, - search: params.search, - level: params.level - }; - return self.getProjectId(params.projectId).then(function (result) { - queryParams.projectId = result; - return self.sendGetRequest(self.getProjectLogsUrl(queryParams, filterParams)); - }).then(function (content) { - return JSON.parse(content); - }); -}; - -module.exports = ServerConnector; +"use strict"; + +/* exported logger */ + +var Promise = require("bluebird"); + +var logger = require('./logger'); + +var request = require('request'); + +var HttpStatus = require('http-status-codes'); + +var Alias = require('./map/data/Alias'); +var Annotation = require('./map/data/Annotation'); +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'); +var InvalidCredentialsError = require('./InvalidCredentialsError'); +var LayoutAlias = require('./map/data/LayoutAlias'); +var LayoutData = require('./map/data/LayoutData'); +var LayoutReaction = require('./map/data/LayoutReaction'); +var MapModel = require('./map/data/MapModel'); +var MiRna = require('./map/data/MiRna'); +var NetworkError = require('./NetworkError'); +var Project = require('./map/data/Project'); +var ProjectStatistics = require('./map/data/ProjectStatistics'); +var Reaction = require('./map/data/Reaction'); +var ReferenceGenome = require('./map/data/ReferenceGenome'); +var SecurityError = require('./SecurityError'); +var SessionData = require('./SessionData'); +var User = require('./map/data/User'); + +var GuiConnector = require('./GuiConnector'); + +var ObjectWithListeners = require('./ObjectWithListeners'); + +/** + * This object contains methods that will communicate with server. + */ +var ServerConnector = new ObjectWithListeners(); +ServerConnector.init = function () { + var self = this; + + self._configurationParam = []; + self._projects = []; + self._projectsById = []; + + self._users = []; + self._usersByLogin = []; + + self._customMap = null; + self._sessionData = undefined; + self._configuration = undefined; + self._loggedUser = undefined; + self._serverBaseUrl = undefined; + + var i; + var listeners = self.getListeners("onDataLoadStart"); + for (i = 0; i < listeners.length; i++) { + self.removeListener("onDataLoadStart", listeners[i]); + } + + listeners = self.getListeners("onDataLoadStop"); + for (i = 0; i < listeners.length; i++) { + self.removeListener("onDataLoadStop", listeners[i]); + } + +}; +ServerConnector.registerListenerType("onDataLoadStart"); +ServerConnector.registerListenerType("onDataLoadStop"); +ServerConnector.init(); + +ServerConnector.getMinOverlayColorInt = function () { + var self = this; + return self.getLoggedUser().then(function (user) { + var userColor = user.getMinColor(); + return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.MIN_COLOR_VAL)); + }); +}; + +ServerConnector.returnUserOrSystemColor = function (userColor, systemPromisedColor) { + return systemPromisedColor.then(function (systemColor) { + var color = userColor; + if (userColor === null || userColor === undefined || userColor === "") { + color = systemColor; + } + color = parseInt(color, 16); + /* jslint bitwise: true */ + color = (color & 0xFFFFFF); + return color; + }); +}; + +ServerConnector.getSimpleOverlayColorInt = function () { + var self = this; + return self.getLoggedUser().then(function (user) { + var userColor = user.getSimpleColor(); + return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.SIMPLE_COLOR_VAL)); + }); +}; + +ServerConnector.getMaxOverlayColorInt = function () { + var self = this; + return self.getLoggedUser().then(function (user) { + var userColor = user.getMaxColor(); + return self.returnUserOrSystemColor(userColor, self.getConfigurationParam(ConfigurationType.MAX_COLOR_VAL)); + }); +}; + +ServerConnector.sendGetRequest = function (url, description) { + return this.sendRequest({ + url: url, + description: description, + method: "GET" + }); +}; + +ServerConnector.sendRequest = function (params) { + var self = this; + if (arguments.length > 1) { + return Promise.reject(new Error("Only two arguments are supported")); + } + + if (self.getSessionData().getToken() === undefined) { + self.getSessionData().setLogin(undefined); + window.location.reload(false); + } + + var description = params.url; + if (params.description !== undefined) { + description = params.description; + params.description = undefined; + } + + var content; + return self.callListeners("onDataLoadStart", description).then(function () { + return self._sendRequest(params); + }).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; + }); + +}; + +ServerConnector._sendRequest = function (params) { + return new Promise(function (resolve, reject) { + request(params, function (error, response, body) { + if (error) { + reject(new NetworkError(error.message, { + content: body, + url: params.url + })); + } else if (response.statusCode !== 200) { + reject(new NetworkError(params.url + " rejected with status code: " + response.statusCode, { + content: body, + url: params.url, + statusCode: response.statusCode + })); + } else { + // for some reason sometimes result is an object not a string + if (typeof body === 'string' || body instanceof String) { + resolve(body); + } else { + resolve(JSON.stringify(body)); + } + } + }); + }); +}; + +ServerConnector.sendPostRequest = function (url, params) { + return this.sendRequest({ + method: "POST", + url: url, + form: params + }); +}; + +ServerConnector.sendDeleteRequest = function (url, json) { + return this.sendRequest({ + method: "DELETE", + url: url, + json: json + }); +}; + +ServerConnector.sendPatchRequest = function (url, json) { + return this.sendRequest({ + method: "PATCH", + url: url, + json: json + }); +}; + +ServerConnector.getToken = function () { + var self = this; + + var login = self.getSessionData(null).getLogin(); + var token = self.getSessionData(null).getToken(); + if (token === undefined || login === 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.getConfiguration().then(function () { + return token; + // if there was an error accessing configuration it means our token is + // invalid + }, function () { + return self.login(); + }); + } else { + return Promise.resolve(token); + } + } +}; + +ServerConnector.getApiBaseUrl = function () { + return this.getServerBaseUrl() + "/api/"; +}; + +ServerConnector.getServerBaseUrl = function () { + if (this._serverBaseUrl === undefined) { + var url = "" + window.location.href; + if (url.indexOf("?") >= 0) { + url = url.substr(0, url.indexOf("?")); + } + if (!url.endsWith("/")) { + url = url.substr(0, url.lastIndexOf("/") + 1); + } + this._serverBaseUrl = url; + } + return this._serverBaseUrl; +}; + +ServerConnector.createGetParams = function (params, prefix) { + var sorted = [], key; + + for (key in params) { + if (params.hasOwnProperty(key)) { + sorted.push(key); + } + } + sorted.sort(); + + var result = ""; + for (var i = 0; i < sorted.length; 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; +}; + +ServerConnector.getApiUrl = function (paramObj) { + var type = paramObj.type; + var params = this.createGetParams(paramObj.params); + + var result = paramObj.url; + if (result === undefined) { + result = this.getApiBaseUrl() + "/" + type; + } + if (params !== "") { + result += "?" + params; + } + return result; +}; + +ServerConnector.getProjectsUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + type: "projects/", + params: filterParams + }); +}; + +ServerConnector.getProjectUrl = function (queryParams, filterParams) { + var id = this.getIdOrAsterisk(queryParams.projectId); + return this.getApiUrl({ + url: this.getProjectsUrl(queryParams) + id + "/", + params: filterParams + }); +}; + +ServerConnector.getProjectStatisticsUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "statistics/", + params: filterParams + }); +}; + +ServerConnector.getPublicationsUrl = function (queryParams, filterParams) { + filterParams.start = filterParams.start || 0; + filterParams.length = filterParams.length || 10; + + return this.getApiUrl({ + url: this.getModelsUrl(queryParams) + "publications/", + params: filterParams + }); +}; +ServerConnector.getProjectLogsUrl = function (queryParams, filterParams) { + filterParams.start = filterParams.start || 0; + filterParams.length = filterParams.length || 10; + + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "logs/", + params: filterParams + }); +}; + + +ServerConnector.getReferenceGenomeUrl = function (queryParams, filterParams) { + var version = this.getIdOrAsterisk(queryParams.version); + + return this.getApiUrl({ + type: "genomics/taxonomies/" + queryParams.organism + "/genomeTypes/" + queryParams.type + "/versions/" + version + + "/", + params: filterParams + }); +}; + +ServerConnector.loginUrl = function () { + return this.getApiUrl({ + type: "/doLogin" + }); +}; + +ServerConnector.logoutUrl = function () { + return this.getApiUrl({ + type: "/doLogout" + }); +}; + +ServerConnector.getSuggestedQueryListUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getBioEntitiesUrl(queryParams) + "suggestedQueryList/", + params: filterParams + }); +}; + +ServerConnector.addCommentUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getCommentsUrl(queryParams) + }); +}; + +ServerConnector.addOverlayUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getOverlaysUrl(queryParams) + }); +}; + +ServerConnector.updateOverlayUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getOverlayByIdUrl(queryParams) + }); +}; + +ServerConnector.deleteOverlayUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getOverlayByIdUrl(queryParams) + }); +}; + +ServerConnector.deleteCommentUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "comments/" + queryParams.commentId + "/" + }); +}; + +ServerConnector.getOverlaysUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "overlays/", + params: filterParams + }); +}; + +ServerConnector.getCommentsUrl = function (queryParams, filterParams) { + var modelId = this.getIdOrAsterisk(queryParams.modelId); + var url = this.getProjectUrl(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({ + url: url, + params: filterParams + }); +}; + +ServerConnector.getOverlayByIdUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getOverlaysUrl(queryParams) + queryParams.overlayId + "/", + params: filterParams + }); + +}; + +ServerConnector.getOverlayElementsUrl = function (queryParams, filterParams) { + + return this.getApiUrl({ + url: this.getModelsUrl(queryParams) + "bioEntities/", + params: filterParams + }); + +}; + +ServerConnector.getFullOverlayElementUrl = function (queryParams, filterParams) { + + return this.getApiUrl({ + url: this.getAliasesUrl(queryParams) + queryParams.id + "/", + params: filterParams + }); + +}; + +ServerConnector.idsToString = function (ids) { + var result = ""; + if (ids !== undefined) { + ids.sort(function (a, b) { + if (typeof a === "string") { + return a.localeCompare(b); + } else { + return a - b; + } + }); + for (var i = 0; i < ids.length; i++) { + if (result !== "") { + if (ids[i - 1] !== ids[i]) { + result = result + "," + ids[i]; + } // we ignore duplicates + } else { + result = ids[i]; + } + } + } + return result; +}; + +ServerConnector.pointToString = function (point) { + return point.x.toFixed(2) + "," + point.y.toFixed(2); +}; + +ServerConnector.getModelsUrl = function (queryParams) { + var modelId = this.getIdOrAsterisk(queryParams.modelId); + var overlayId = queryParams.overlayId; + var url = this.getProjectUrl(queryParams); + if (overlayId !== undefined) { + url = this.getOverlayByIdUrl(queryParams); + } + + return this.getApiUrl({ + url: url + "models/" + modelId + "/" + }); +}; + +ServerConnector.getBioEntitiesUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getModelsUrl(queryParams) + "bioEntities/" + }); +}; + +ServerConnector.getIdOrAsterisk = function (id) { + if (id === undefined || id === "" || id === null) { + return "*"; + } else { + return id; + } +}; + +ServerConnector.getReactionsUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getBioEntitiesUrl(queryParams) + "reactions/", + params: filterParams + }); +}; + +ServerConnector.getAliasesUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getBioEntitiesUrl(queryParams) + "elements/", + params: filterParams + }); +}; + +ServerConnector.getConfigurationUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + type: "configuration/", + params: filterParams + }); +}; + +ServerConnector.getConfigurationOptionUrl = function (queryParams, filterParams) { + var self = this; + return self.getApiUrl({ + url: self.getConfigurationUrl() + "options/" + queryParams.type, + params: filterParams + }); +}; + + +ServerConnector.getSearchUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getModelsUrl(queryParams) + "bioEntities:search", + params: filterParams + }); +}; + +ServerConnector.getSearchDrugsUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "drugs:search", + params: filterParams + }); +}; + +ServerConnector.getSearchMiRnasUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "miRnas:search", + params: filterParams + }); +}; + +ServerConnector.getSearchChemicalsUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "chemicals:search", + params: filterParams + }); +}; + +ServerConnector.getOverlaySourceUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getOverlaysUrl(queryParams) + queryParams.overlayId + ":downloadSource", + params: filterParams + }); +}; + +ServerConnector.getImageUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "models/" + queryParams.modelId + ":downloadImage", + params: filterParams + }); +}; + +ServerConnector.getModelPartUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getProjectUrl(queryParams) + "models/" + queryParams.modelId + ":downloadModel", + params: filterParams + }); +}; + +ServerConnector.getProjectSourceUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + type: "projects/" + queryParams.projectId + ":downloadSource", + params: filterParams + }); +}; + + +ServerConnector.getFilesUrl = function () { + return this.getApiUrl({ + type: "files/" + }); +}; + +ServerConnector.getCreateFileUrl = function () { + return this.getApiUrl({ + url: this.getFilesUrl() + }); +}; +ServerConnector.getFileUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getFilesUrl() + "/" + queryParams.id + }); +}; +ServerConnector.getUploadFileUrl = function (queryParams) { + return this.getApiUrl({ + url: this.getFileUrl(queryParams) + ":uploadContent" + }); +}; + + +ServerConnector.getUsersUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + type: "users/", + params: filterParams + }); +}; + +ServerConnector.getUserUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getUsersUrl() + queryParams.login, + params: filterParams + }); +}; + +ServerConnector.getUpdateUserPrivilegesUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getUserUrl(queryParams) + ":updatePrivileges", + params: filterParams + }); +}; +ServerConnector.getUpdateUserPreferencesUrl = function (queryParams, filterParams) { + return this.getApiUrl({ + url: this.getUserUrl(queryParams) + ":updatePreferences", + params: filterParams + }); +}; + +ServerConnector.getConfiguration = function () { + var self = this; + if (this._configuration === undefined) { + return self.sendGetRequest(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) { + if (paramId === undefined) { + return Promise.reject(new Error("Unknown param type")); + } + var self = this; + return self.getConfiguration().then(function (configuration) { + var option = configuration.getOption(paramId); + if (option.getValue !== undefined) { + return option.getValue(); + } else { + return option; + } + }); +}; +ServerConnector.updateConfigurationOption = function (option) { + var self = this; + var queryParams = { + type: option.getType() + }; + var filterParams = { + option: { + type: option.getType(), + value: option.getValue() + } + }; + return self.sendPatchRequest(self.getConfigurationOptionUrl(queryParams), filterParams); +}; + +ServerConnector.getModels = function (projectId) { + var queryParams = {}; + var filterParams = {}; + var self = this; + return self.getProjectId(projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getModelsUrl(queryParams, filterParams)); + }).then(function (content) { + var models = []; + var parsedJson = JSON.parse(content); + for (var i = 0; i < parsedJson.length; i++) { + models.push(new MapModel(parsedJson[i])); + } + return models; + }); +}; + +ServerConnector.getProject = function (projectId) { + var queryParams = {}; + var filterParams = {}; + var project; + var self = this; + return self.getProjectId(projectId).then(function (result) { + projectId = result; + queryParams.projectId = result; + return self.sendGetRequest(self.getProjectUrl(queryParams, filterParams)); + }).then(function (content) { + var downloadedProject = new Project(content); + if (self._projectsById[projectId] !== undefined) { + self._projectsById[projectId].update(downloadedProject); + } else { + self._projectsById[projectId] = downloadedProject; + } + project = self._projectsById[projectId]; + return self.getModels(projectId); + }).then(function (models) { + project.setModel(models[0]); + return self.getLoggedUser(); + }).then(function (user) { + return self.getOverlays({ + projectId: projectId, + creator: user.getLogin(), + publicOverlay: false + }); + }).then(function (overlays) { + if (project.getModel() !== undefined) { + project.getModel().addLayouts(overlays); + } else { + if (overlays.length > 0) { + logger.warn("Cannot add overlays to the project: " + project.getProjectId()); + } + } + return project; + }).then(null, function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.NOT_FOUND: + return null; + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } + }); +}; + +ServerConnector.updateProject = function (project) { + var self = this; + var queryParams = { + projectId: project.getProjectId() + }; + var filterParams = { + project: { + name: project.getName(), + version: project.getVersion(), + notifyEmail: project.getNotifyEmail(), + organism: self.serialize(project.getOrganism()), + disease: self.serialize(project.getDisease()) + } + }; + return self.sendPatchRequest(self.getProjectUrl(queryParams), filterParams).then(function (content) { + var downloadedProject = new Project(content); + project.update(downloadedProject); + return project; + }).then(null, function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } + }); +}; + +ServerConnector.removeProject = function (projectId) { + var self = this; + var queryParams = { + projectId: projectId + }; + return self.sendDeleteRequest(self.getProjectUrl(queryParams)).then(function (content) { + var project = new Project(content); + if (self._projectsById[project.getProjectId()] !== undefined) { + self._projectsById[project.getProjectId()].update(project); + } else { + self._projectsById[project.getProjectId()] = project; + } + return self._projectsById[project.getProjectId()]; + }).then(null, function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } + }); +}; + +ServerConnector.addProject = function (options) { + var self = this; + var queryParams = { + projectId: options.projectId + }; + return self.sendPostRequest(self.getProjectUrl(queryParams), options).then(function (content) { + var project = new Project(content); + if (self._projectsById[project.getProjectId()] !== undefined) { + self._projectsById[project.getProjectId()].update(project); + } else { + self._projectsById[project.getProjectId()] = project; + } + return project; + }).then(null, function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } + }); +}; + +ServerConnector.serialize = function (object) { + var result = {}; + if (object instanceof Annotation) { + result.type = object.getType(); + result.resource = object.getResource(); + } else { + throw new Error("Unhandled object type: " + (typeof object)); + } + return result; +}; + +ServerConnector.getProjects = function (reload) { + var self = this; + if (self._projects.length > 0 && !reload) { + return Promise.resolve(self._projects); + } else { + return self.sendGetRequest(self.getProjectsUrl()).then(function (content) { + var parsedData = JSON.parse(content); + self._projects.length = 0; + for (var i = 0; i < parsedData.length; i++) { + var project = new Project(JSON.stringify(parsedData[i])); + if (self._projectsById[project.getProjectId()] !== undefined) { + self._projectsById[project.getProjectId()].update(project); + } else { + self._projectsById[project.getProjectId()] = project; + } + self._projects.push(self._projectsById[project.getProjectId()]); + } + return self._projects; + }); + } +}; + +ServerConnector.getProjectStatistics = function (projectId) { + var queryParams = {}; + var filterParams = {}; + var self = this; + var content; + return self.getProjectId(projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getProjectStatisticsUrl(queryParams, filterParams)); + }).then(function (result) { + content = JSON.parse(result); + return self.getConfiguration(); + }).then(function (configuration) { + return new ProjectStatistics(content, configuration); + }); +}; + +ServerConnector.getLoggedUser = function () { + var self = this; + if (self._loggedUser !== undefined) { + return Promise.resolve(self._loggedUser); + } else { + return self.getUser(self.getSessionData().getLogin()).then(function (user) { + self._loggedUser = user; + return self._loggedUser; + }); + } +}; + +ServerConnector.getUser = function (login) { + var self = this; + var queryParams = { + login: login + }; + var filterParams = {}; + + return self.sendGetRequest(self.getUserUrl(queryParams, filterParams)).then(function (content) { + var obj = JSON.parse(content); + var user = new User(obj); + if (self._usersByLogin[user.getLogin()] !== undefined) { + self._usersByLogin[user.getLogin()].update(user); + } else { + self._usersByLogin[user.getLogin()] = user; + } + return self._usersByLogin[user.getLogin()]; + }).then(null, function (error) { + return self.processNetworkError(error); + }); +}; + +ServerConnector.updateUser = function (user) { + var self = this; + var queryParams = { + login: user.getLogin() + }; + var filterParams = { + user: { + name: user.getName(), + surname: user.getSurname(), + password: user.getPassword(), + email: user.getEmail() + } + }; + return self.sendPatchRequest(self.getUserUrl(queryParams), filterParams).then(function () { + return self.getConfiguration(); + }).then(function (configuration) { + return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); + }); + +}; +ServerConnector.addUser = function (user) { + var self = this; + var queryParams = { + login: user.getLogin() + }; + var filterParams = { + login: user.getLogin(), + name: user.getName(), + surname: user.getSurname(), + password: user.getPassword(), + email: user.getEmail() + }; + return self.sendPostRequest(self.getUserUrl(queryParams), filterParams).then(function () { + return self.getConfiguration(); + }).then(function (configuration) { + return self.updateUserPrivileges({user: user, privileges: user.privilegesToExport(configuration)}); + }); + +}; + +ServerConnector.removeUser = function (login) { + var self = this; + var queryParams = { + login: login + }; + return self.sendDeleteRequest(self.getUserUrl(queryParams)); + +}; + +ServerConnector.updateUserPrivileges = function (params) { + var self = this; + var queryParams = { + login: params.user.getLogin() + }; + + return self.sendPatchRequest(self.getUpdateUserPrivilegesUrl(queryParams), { + privileges: params.privileges + }).then(function (content) { + var obj = JSON.parse(content); + var user = new User(obj); + if (self._usersByLogin[user.getLogin()] !== undefined) { + self._usersByLogin[user.getLogin()].update(user); + } else { + self._usersByLogin[user.getLogin()] = user; + } + return self._usersByLogin[user.getLogin()]; + }).then(null, function (error) { + return self.processNetworkError(error); + }); +}; + +ServerConnector.processNetworkError = function (error) { + if ((error instanceof NetworkError)) { + switch (error.statusCode) { + case HttpStatus.NOT_FOUND: + return null; + case HttpStatus.FORBIDDEN: + return Promise.reject(new SecurityError("Access denied.")); + default: + return Promise.reject(error); + } + } else { + return Promise.reject(error); + } +}; + + +ServerConnector.updateUserPreferences = function (params) { + var self = this; + var queryParams = { + login: params.user.getLogin() + }; + + return self.sendPatchRequest(self.getUpdateUserPreferencesUrl(queryParams), { + preferences: params.preferences.toExport() + }).then(function (content) { + var obj = JSON.parse(content); + var user = new User(obj); + if (self._usersByLogin[user.getLogin()] !== undefined) { + self._usersByLogin[user.getLogin()].update(user); + } else { + self._usersByLogin[user.getLogin()] = user; + } + return self._usersByLogin[user.getLogin()]; + }); +}; + +ServerConnector.getUsers = function (forceRefresh) { + var self = this; + + if (self._users.length > 0 && !forceRefresh) { + return Promise.resolve(self._users); + } else { + return self.sendGetRequest(self.getUsersUrl()).then(function (content) { + var parsedData = JSON.parse(content); + self._users.length = 0; + for (var i = 0; i < parsedData.length; i++) { + var user = new User(parsedData[i]); + if (self._usersByLogin[user.getLogin()] !== undefined) { + self._usersByLogin[user.getLogin()].update(user); + } else { + self._usersByLogin[user.getLogin()] = user; + } + self._users.push(self._usersByLogin[user.getLogin()]); + } + return self._users; + }); + } + +}; + +ServerConnector.getOverlays = function (params) { + var self = this; + if (params === undefined) { + params = {}; + } + var queryParams = {}; + var filterParams = { + creator: params.creator, + publicOverlay: params.publicOverlay + }; + return new Promise(function (resolve, reject) { + self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getOverlaysUrl(queryParams, filterParams)); + }).then(function (content) { + var arr = JSON.parse(content); + var result = []; + for (var i = 0; i < arr.length; i++) { + var overlay = new LayoutData(arr[i]); + result.push(overlay); + } + resolve(result); + }, reject); + }); +}; + +ServerConnector.getOverlayElements = function (overlayId, projectId) { + var self = this; + if (overlayId === undefined) { + throw new Error("Layout id must be defined"); + } + var queryParams = { + overlayId: overlayId, + modelId: "*" + }; + var filterParams = {}; + return self.getProjectId(projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getOverlayElementsUrl(queryParams, filterParams)); + }).then(function (content) { + var arr = JSON.parse(content); + var result = []; + for (var i = 0; i < arr.length; i++) { + var element = arr[i]; + if (element.type === "REACTION") { + result.push(new LayoutReaction(element.overlayContent)); + } else if (element.type === "ALIAS") { + result.push(new LayoutAlias(element.overlayContent)); + } else { + throw new Error("Unknown element type: " + element.type); + } + } + return result; + }); +}; + +ServerConnector.getFullOverlayElement = function (params) { + var self = this; + + 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.sendGetRequest(self.getFullOverlayElementUrl(queryParams, filterParams)); + }).then(function (content) { + var element = JSON.parse(content); + var result = null; + if (element.type === "REACTION") { + result = new LayoutReaction(element.overlayContent); + } else if (element.type === "ALIAS") { + result = new LayoutAlias(element.overlayContent); + } else { + throw new Error("Unknown element type: " + element.type); + } + return result; + }); +}; + +ServerConnector.getProjectId = function (projectId) { + var self = this; + if (projectId !== undefined && projectId !== null && projectId !== "") { + return Promise.resolve(projectId); + } else if (GuiConnector.getParams['id'] !== undefined) { + return Promise.resolve(GuiConnector.getParams['id']); + } else { + return self.getConfigurationParam(ConfigurationType.DEFAULT_MAP); + } +}; + +ServerConnector.getLogoImg = function () { + return this.getConfigurationParam(ConfigurationType.LOGO_IMG); +}; + +ServerConnector.getLogoLink = function () { + return this.getConfigurationParam(ConfigurationType.LOGO_LINK); +}; + +ServerConnector.getMaxSearchDistance = function () { + return this.getConfigurationParam(ConfigurationType.SEARCH_DISTANCE); +}; + +ServerConnector.getOverlayById = function (overlayId, projectId) { + var self = this; + var queryParams = { + overlayId: overlayId + }; + var filterParams = {}; + return self.getProjectId(projectId).then(function (data) { + queryParams.projectId = data; + return self.sendGetRequest(self.getOverlayByIdUrl(queryParams, filterParams)); + }).then(function (content) { + return new LayoutData(JSON.parse(content)); + }); +}; + +ServerConnector.getReactions = function (params) { + var self = this; + var queryParams = {}; + if (params.ids === undefined) { + params.ids = []; + } + if (params.participantId === undefined) { + params.participantId = []; + } + var filterParams = { + id: params.ids, + columns: params.columns, + participantId: params.participantId + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + if (filterParams.id.length > 100 || filterParams.participantId.length > 100) { + return self.sendPostRequest(self.getReactionsUrl(queryParams), filterParams); + } else { + return self.sendGetRequest(self.getReactionsUrl(queryParams, filterParams)); + } + + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new Reaction(array[i])); + } + return result; + }); +}; + +ServerConnector.getAliases = function (params) { + var self = this; + var queryParams = { + modelId: params.modelId + }; + if (params.ids === undefined) { + params.ids = []; + } + if (params.includedCompartmentIds === undefined) { + params.includedCompartmentIds = []; + } + if (params.excludedCompartmentIds === undefined) { + params.excludedCompartmentIds = []; + } + var filterParams = { + id: params.ids, + columns: params.columns, + type: params.type, + excludedCompartmentIds: params.excludedCompartmentIds, + includedCompartmentIds: params.includedCompartmentIds + + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + if (filterParams.id.length > 100) { + return self.sendPostRequest(self.getAliasesUrl(queryParams), filterParams); + } else { + return self.sendGetRequest(self.getAliasesUrl(queryParams, filterParams)); + } + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new Alias(array[i])); + } + return result; + }); +}; + +ServerConnector.getLightComments = function (params) { + params.columns = ["id", "elementId", "modelId", "type", "icon", "removed", "pinned"]; + return this.getComments(params); +}; + +ServerConnector.getComments = function (params) { + var self = this; + var queryParams = { + elementId: params.elementId, + elementType: params.elementType, + coordinates: params.coordinates + }; + var filterParams = { + columns: params.columns + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getCommentsUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new Comment(array[i])); + } + return result; + }); +}; + +ServerConnector.getSessionData = function (project) { + if (this._sessionData === undefined) { + this._sessionData = new SessionData(project); + } + if (project !== undefined && this._sessionData.getProject() === null) { + this._sessionData.setProject(project); + } + return this._sessionData; +}; + +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) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new IdentifiedElement(array[i])); + } + return result; + }); +}; + +ServerConnector.login = function (login, password) { + var self = this; + var params = {}; + if (login !== undefined && login !== "") { + params.login = login; + params.password = password; + } else { + params.login = "anonymous"; + } + self.getSessionData().setToken(""); + return self.sendPostRequest(self.loginUrl(), params).then(function () { + self.getSessionData().setLogin(params.login); + return Promise.resolve(self.getSessionData().getToken()); + }, function (error) { + if (error instanceof NetworkError && error.statusCode === HttpStatus.FORBIDDEN) { + throw new InvalidCredentialsError("Invalid credentials"); + } else { + throw error; + } + }); +}; + +ServerConnector.logout = function () { + var self = this; + self.getSessionData().setToken(undefined); + self.getSessionData().setLogin(undefined); + return self.sendGetRequest(self.logoutUrl()); +}; + +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) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new IdentifiedElement(array[i])); + } + return result; + }); +}; + +ServerConnector.getDrugsByQuery = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + query: params.query + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchDrugsUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new Drug(array[i])); + } + return result; + }); +}; + +ServerConnector.getMiRnasByQuery = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + query: params.query + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchMiRnasUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new MiRna(array[i])); + } + return result; + }); +}; + +ServerConnector.getChemicalsByQuery = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + query: params.query + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchChemicalsUrl(queryParams, filterParams)); + }).then(function (content) { + var array = JSON.parse(content); + var result = []; + for (var i = 0; i < array.length; i++) { + result.push(new Chemical(array[i])); + } + return result; + }); +}; + +ServerConnector.getOverlaySourceDownloadUrl = function (params) { + var self = this; + var queryParams = { + overlayId: params.overlayId + }; + var filterParams = {}; + return self.getProjectId(params.projectId).then(function (result) { + 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) { + 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) { + queryParams.projectId = result; + return self.getModelPartUrl(queryParams, filterParams); + }); +}; + +ServerConnector.getImageConverters = function () { + var self = this; + return self.getConfiguration().then(function (configuration) { + return configuration.getImageConverters(); + }); +}; +ServerConnector.getModelConverters = function () { + var self = this; + return self.getConfiguration().then(function (configuration) { + return configuration.getModelConverters(); + }); +}; + +ServerConnector.getProjectSourceDownloadUrl = function (params) { + if (params === undefined) { + params = {}; + } + var queryParams = {}; + var filterParams = {}; + var self = this; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.getProjectSourceUrl(queryParams, filterParams); + }); +}; + +ServerConnector.getDrugNamesByTarget = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + columns: ["name"], + target: params.target.getType() + ":" + params.target.getId() + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchDrugsUrl(queryParams, filterParams)); + }).then(function (content) { + var result = []; + var object = JSON.parse(content); + for (var i = 0; i < object.length; i++) { + result.push(object[i].name); + } + return result; + }); +}; + +ServerConnector.getMiRnaNamesByTarget = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + columns: ["name"], + target: params.target.getType() + ":" + params.target.getId() + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchMiRnasUrl(queryParams, filterParams)); + }).then(function (content) { + var result = []; + var object = JSON.parse(content); + for (var i = 0; i < object.length; i++) { + result.push(object[i].name); + } + return result; + }); +}; + +ServerConnector.getChemicalNamesByTarget = function (params) { + var self = this; + var queryParams = {}; + var filterParams = { + columns: ["name"], + target: params.target.getType() + ":" + params.target.getId() + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getSearchChemicalsUrl(queryParams, filterParams)); + }).then(function (content) { + var result = []; + var object = JSON.parse(content); + for (var i = 0; i < object.length; i++) { + result.push(object[i].name); + } + return result; + }); +}; + +ServerConnector.addComment = function (params) { + var self = this; + 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 overlay = params.overlay; + if (!(overlay instanceof LayoutData)) { + throw new Error("Invalid overlay: " + overlay); + } + var self = this; + var queryParams = {}; + var data = { + name: overlay.getName(), + description: overlay.getDescription(), + content: overlay.getContent(), + filename: overlay.getFilename(), + fileId: params.fileId + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendPostRequest(self.addOverlayUrl(queryParams), data); + }).then(function (content) { + return new LayoutData(JSON.parse(content)); + }); +}; + +ServerConnector.updateOverlay = function (overlay) { + var self = this; + var queryParams = { + overlayId: overlay.getId() + }; + var filterParams = { + overlay: { + name: overlay.getName(), + description: overlay.getDescription(), + creator: overlay.getCreator(), + publicOverlay: overlay.getPublicOverlay() + } + }; + return self.sendPatchRequest(self.updateOverlayUrl(queryParams), filterParams); +}; + +ServerConnector.removeOverlay = function (params) { + var self = this; + 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); + }); +}; + +ServerConnector.removeComment = function (params) { + var self = this; + var queryParams = { + commentId: params.commentId + }; + var filterParams = {}; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendDeleteRequest(self.deleteCommentUrl(queryParams), filterParams); + }); +}; + +ServerConnector.getSuggestedQueryList = function (projectId) { + var self = this; + return self.getProjectId(projectId).then(function (result) { + projectId = result; + return self.sendGetRequest(self.getSuggestedQueryListUrl({ + projectId: projectId + })); + }).then(function (content) { + return JSON.parse(content); + }); +}; + +ServerConnector.getOverlayTypes = function () { + var self = this; + return self.getConfiguration().then(function (configuration) { + return configuration.getOverlayTypes(); + }); +}; + +ServerConnector.getPublications = function (params) { + var self = this; + if (params === undefined) { + params = {}; + } + + var queryParams = {}; + var filterParams = { + start: params.start, + length: params.length, + sortColumn: params.sortColumn, + sortOrder: params.sortOrder, + search: params.search + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getPublicationsUrl(queryParams, filterParams)); + }).then(function (content) { + return JSON.parse(content); + }); +}; + +ServerConnector.getReferenceGenome = function (params) { + var self = this; + var filterParams = {}; + return self.sendGetRequest(self.getReferenceGenomeUrl(params, filterParams)).then(function (content) { + return new ReferenceGenome(JSON.parse(content)); + }); +}; + +ServerConnector.uploadFile = function (params) { + var CHUNK_SIZE = 65535; + var self = this; + var data = new Uint8Array(params.content); + var filterParams = { + filename: params.filename, + length: data.length + }; + + return self.sendPostRequest(self.getCreateFileUrl(), filterParams).then(function (response) { + var uploadedLength = 0; + var createPromise = function (resultFileJson) { + var resultFile = JSON.parse(resultFileJson); + if (uploadedLength >= data.length) { + return Promise.resolve(resultFile); + } else { + var chunk = data.slice(uploadedLength, uploadedLength + CHUNK_SIZE); + var url = self.getUploadFileUrl({id: resultFile.id}); + return self.sendRequest({method: "POST", url: url, body: chunk}).then(function (resultFileJson) { + uploadedLength += chunk.length; + return createPromise(resultFileJson); + }) + } + }; + return createPromise(response); + }); +}; + + +ServerConnector.getProjectLogs = function (params) { + var self = this; + if (params === undefined) { + params = {}; + } + + var queryParams = {}; + var filterParams = { + start: params.start, + length: params.length, + sortColumn: params.sortColumn, + sortOrder: params.sortOrder, + search: params.search, + level: params.level + }; + return self.getProjectId(params.projectId).then(function (result) { + queryParams.projectId = result; + return self.sendGetRequest(self.getProjectLogsUrl(queryParams, filterParams)); + }).then(function (content) { + return JSON.parse(content); + }); +}; + +module.exports = ServerConnector; diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js index 4697a5357a..a0dbacbc1b 100644 --- a/frontend-js/src/main/js/gui/AddOverlayDialog.js +++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js @@ -15,6 +15,7 @@ var logger = require('../logger'); var HttpStatus = require('http-status-codes'); var Promise = require("bluebird"); +var TextEncoder = require('text-encoding').TextEncoder; function AddOverlayDialog(params) { AbstractGuiElement.call(this, params); @@ -36,7 +37,7 @@ AddOverlayDialog.prototype.createGui = function () { var nameInput = Functions.createElement({ type: "input", inputType: "text", - name: "overlay-name", + name: "overlay-name" }); content.appendChild(nameInput); content.appendChild(guiUtils.createNewLine()); @@ -45,7 +46,7 @@ AddOverlayDialog.prototype.createGui = function () { content.appendChild(guiUtils.createNewLine()); var descriptionInput = Functions.createElement({ type: "textarea", - name: "overlay-description", + name: "overlay-description" }); content.appendChild(descriptionInput); content.appendChild(guiUtils.createNewLine()); @@ -54,10 +55,10 @@ AddOverlayDialog.prototype.createGui = function () { var fileInput = Functions.createElement({ type: "input", inputType: "file", - name: "overlay-file", + name: "overlay-file" }); fileInput.addEventListener("change", function () { - return self.processFile(fileInput.files[0]); + return self.processFile(fileInput.files[0]).then(null, GuiConnector.alert); }, false); content.appendChild(fileInput); content.appendChild(guiUtils.createNewLine()); @@ -66,7 +67,7 @@ AddOverlayDialog.prototype.createGui = function () { content.appendChild(guiUtils.createNewLine()); var contentInput = Functions.createElement({ type: "textarea", - name: "overlay-content", + name: "overlay-content" }); content.appendChild(contentInput); content.appendChild(guiUtils.createNewLine()); @@ -80,7 +81,7 @@ AddOverlayDialog.prototype.processFile = function (file) { if (file) { return new Promise(function (resolve, reject) { var reader = new FileReader(); - reader.readAsText(file, "UTF-8"); + reader.readAsArrayBuffer(file); reader.onload = function (evt) { try { var overlayParser = new OverlayParser(); @@ -119,6 +120,10 @@ AddOverlayDialog.prototype.processFile = function (file) { }; AddOverlayDialog.prototype.setFileContent = function (fileContent) { + if (typeof fileContent === 'string' || fileContent instanceof String) { + fileContent = new TextEncoder("UTF8").encode(fileContent); + } + this._fileContent = fileContent; }; @@ -129,7 +134,7 @@ AddOverlayDialog.prototype.getFileContent = function () { if (contentInput.value !== undefined && contentInput.value !== null) { contentInput.value = contentInput.value.trim(); if (contentInput.value !== "") { - self._fileContent = contentInput.value; + self.setFileContent(contentInput.value); } } if (self._fileContent === undefined) { @@ -151,13 +156,21 @@ AddOverlayDialog.prototype.addOverlay = function () { var overlay = new LayoutData({ name: nameInput.value, description: descriptionInput.value, - content: self.getFileContent(), - filename: filename, + filename: filename }); + if (filename === undefined || filename === "") { + filename = "unknown.txt"; + } GuiConnector.showProcessing(); - return ServerConnector.addOverlay({ - overlay: overlay, - projectId: self.getProject().getProjectId(), + return ServerConnector.uploadFile({ + filename: filename, + content: self.getFileContent() + }).then(function (file) { + return ServerConnector.addOverlay({ + fileId: file.id, + overlay: overlay, + projectId: self.getProject().getProjectId() + }); }).then(function (result) { overlay = result; GuiConnector.hideProcessing(); @@ -180,8 +193,6 @@ AddOverlayDialog.prototype.open = function () { var fileContent = self.getFileContent(); if (fileContent === null) { GuiConnector.alert("Neither file was selected nor data was entered"); - } else if (fileContent.length > 1024 * 256) { - GuiConnector.alert("File to big.<br>Please reduce file size or contact administrators."); } else { return self.addOverlay().then(function (result) { $(dialog).dialog("close"); @@ -207,7 +218,7 @@ AddOverlayDialog.prototype.open = function () { $(div).dialog({ title: "Add overlay", buttons: buttons, - modal: true, + modal: true }); } diff --git a/frontend-js/src/main/js/map/OverlayParser.js b/frontend-js/src/main/js/map/OverlayParser.js index 31fc9bc086..eebe2c5afa 100644 --- a/frontend-js/src/main/js/map/OverlayParser.js +++ b/frontend-js/src/main/js/map/OverlayParser.js @@ -2,11 +2,15 @@ var logger = require('./../logger'); var LayoutData = require('./data/LayoutData'); +var TextDecoder = require('text-encoding').TextDecoder; function OverlayParser() { } OverlayParser.prototype.parse = function (content) { + if (content instanceof Uint8Array || content instanceof ArrayBuffer) { + content = new TextDecoder("UTF8").decode(content); + } var data = {content: content}; var lines = content.split("\n"); for (var i = 0; i < lines.length; i++) { diff --git a/frontend-js/src/test/js/ServerConnector-test.js b/frontend-js/src/test/js/ServerConnector-test.js index 0e756aae63..c45b1b0ef2 100644 --- a/frontend-js/src/test/js/ServerConnector-test.js +++ b/frontend-js/src/test/js/ServerConnector-test.js @@ -187,7 +187,7 @@ describe('ServerConnector', function () { description: "test desc", content: "name color\nCAPN1 #00FF00\nPARK7 #AC0000", filename: "test.txt" - }), + }) }).then(function (overlay) { assert.ok(overlay); }); diff --git a/frontend-js/src/test/js/map/OverlayParser-test.js b/frontend-js/src/test/js/map/OverlayParser-test.js index b3a0f0ae08..053ce56f09 100644 --- a/frontend-js/src/test/js/map/OverlayParser-test.js +++ b/frontend-js/src/test/js/map/OverlayParser-test.js @@ -3,9 +3,12 @@ require("../mocha-config.js"); var OverlayParser = require('../../../main/js/map/OverlayParser'); +var ServerConnector = require('../ServerConnector-mock'); var chai = require('chai'); var assert = chai.assert; +var TextEncoder = require('text-encoding').TextEncoder; + describe('OverlayParser', function () { describe('parse', function () { it('simple', function () { @@ -18,6 +21,16 @@ describe('OverlayParser', function () { assert.equal(overlay.getName(), "some Name"); assert.ok(overlay.getContent()); }); + it('Uint8Array', function () { + var parser = new OverlayParser(); + var fileContent = new TextEncoder("UTF8").encode("#NAME=some Name\n#DESCRIPTION=xxx\nname\tvalue\ns1\t1"); + + var overlay = parser.parse(fileContent); + assert.ok(overlay); + assert.equal(overlay.getDescription(), "xxx"); + assert.equal(overlay.getName(), "some Name"); + assert.ok(overlay.getContent()); + }); it('with type', function () { return ServerConnector.sendGetRequest("testFiles/overlay/good.txt").then(function (fileContent) { diff --git a/frontend-js/testFiles/apiCalls/files/6792.uploadContent/POST_token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/files/6792.uploadContent/POST_token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000..ba783ddb69 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/files/6792.uploadContent/POST_token=MOCK_TOKEN_ID& @@ -0,0 +1,7 @@ +{ + "owner": "admin", + "filename": "unknown.txt", + "uploadedDataLength": 5, + "length": 5, + "id": 6792 +} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/files/POST_filename=unknown.txt&length=3&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/files/POST_filename=unknown.txt&length=3&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000..b31d8d33b7 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/files/POST_filename=unknown.txt&length=3&token=MOCK_TOKEN_ID& @@ -0,0 +1,7 @@ +{ + "owner": "admin", + "filename": "test.txt", + "uploadedDataLength": 0, + "length": 3, + "id": 6792 +} \ No newline at end of file diff --git a/frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_content=s1%0A&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_fileId=6792&token=MOCK_TOKEN_ID& similarity index 100% rename from frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_content=s1%0A&token=MOCK_TOKEN_ID& rename to frontend-js/testFiles/apiCalls/projects/sample/overlays/POST_fileId=6792&token=MOCK_TOKEN_ID& 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 index 5fdd11869d..409f066fa6 100644 --- 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 @@ -29,139 +29,145 @@ import lcsb.mapviewer.services.view.LayoutView; @RestController public class OverlayController extends BaseController { - /** - * Default class logger. - */ - @SuppressWarnings("unused") - 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, // - @RequestParam(value = "creator", defaultValue = "") String creator, // - @RequestParam(value = "publicOverlay", defaultValue = "") String publicOverlay // - ) throws SecurityException, QueryException { - return overlayRestImp.getOverlayList(token, projectId, creator, publicOverlay); - } - - @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; - } + /** + * Default class logger. + */ + @SuppressWarnings("unused") + 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, // + @RequestParam(value = "creator", defaultValue = "") String creator, // + @RequestParam(value = "publicOverlay", defaultValue = "") String publicOverlay // + ) throws SecurityException, QueryException { + return overlayRestImp.getOverlayList(token, projectId, creator, publicOverlay); + } + + @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", defaultValue = "") String content, // + @RequestParam(value = "fileId", defaultValue = "") String fileId, // + @RequestParam(value = "filename") String filename, // + @RequestParam(value = "type", defaultValue = "") String type // + ) throws SecurityException, QueryException, IOException { + return overlayRestImp.addOverlay(token, projectId, name, description, content, fileId, 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/projects/overlays/OverlayRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java index b4a9be35b8..767e2a174d 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/overlays/OverlayRestImpl.java @@ -17,14 +17,14 @@ import lcsb.mapviewer.api.BaseRestImpl; import lcsb.mapviewer.api.ObjectNotFoundException; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.common.Configuration; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.cache.FileEntry; +import lcsb.mapviewer.model.cache.UploadedFileEntry; 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.cache.UploadedFileEntryDao; import lcsb.mapviewer.persist.dao.map.LayoutDao; import lcsb.mapviewer.services.SecurityException; import lcsb.mapviewer.services.interfaces.ILayoutService; @@ -44,11 +44,15 @@ public class OverlayRestImpl extends BaseRestImpl { /** * Default class logger. */ + @SuppressWarnings("unused") private Logger logger = Logger.getLogger(OverlayRestImpl.class); @Autowired private ILayoutService layoutService; + @Autowired + private UploadedFileEntryDao uploadedFileEntryDao; + @Autowired private LayoutDao layoutDao; @@ -237,7 +241,7 @@ public class OverlayRestImpl extends BaseRestImpl { } public LayoutView addOverlay(String token, String projectId, String name, String description, String content, - String filename, String type) throws SecurityException, QueryException, IOException { + String fileId, String filename, String type) throws SecurityException, QueryException, IOException { AuthenticationToken authenticationToken = getUserService().getToken(token); User user = getUserService().getUserByToken(token); if (Configuration.ANONYMOUS_LOGIN.equals(user.getLogin())) { @@ -248,7 +252,6 @@ public class OverlayRestImpl extends BaseRestImpl { throw new QueryException("Project with given id doesn't exist"); } ColorSchemaType colorSchemaType = ColorSchemaType.GENERIC; - logger.debug("TYPE: \'" + type + "\'"); if (type != null && !type.equals("")) { try { colorSchemaType = ColorSchemaType.valueOf(type); @@ -256,9 +259,29 @@ public class OverlayRestImpl extends BaseRestImpl { throw new QueryException("Invalid type of overlay: " + type, e); } } + if (content.isEmpty() && fileId.isEmpty()) { + throw new QueryException("Either content or fileId must be provided"); + } try { - InputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + InputStream stream = null; + if (!content.isEmpty()) { + stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)); + } else { + try { + int id = Integer.valueOf(fileId); + UploadedFileEntry file = uploadedFileEntryDao.getById(id); + if (file == null) { + throw new QueryException("Invalid file id: " + fileId); + } + if (file.getOwner() == null || !file.getOwner().getLogin().equals(user.getLogin())) { + throw new SecurityException("Access denied to source file"); + } + stream = new ByteArrayInputStream(file.getFileContent()); + } catch (NumberFormatException e) { + throw new QueryException("Invalid fileId: " + fileId); + } + } LayoutView layout = layoutService.createLayout(new CreateLayoutParams().async(false).colorInputStream(stream) .description(description).layoutFileName(filename).model(model).name(name).user(user) diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java index efc220594a..074b22ed0a 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/projects/ProjectRestImplTest.java @@ -243,7 +243,7 @@ public class ProjectRestImplTest extends RestTestFunctions { Map<?, ?> elementAnnotations = (Map<?, ?>) result.get("elementAnnotations"); assertEquals(elementAnnotations.get(MiriamType.CAS), 0); - assertEquals(elementAnnotations.get(MiriamType.ENTREZ), 1); + assertTrue((Integer) elementAnnotations.get(MiriamType.ENTREZ) > 0); Map<?, ?> reactionAnnotations = (Map<?, ?>) result.get("reactionAnnotations"); assertEquals(reactionAnnotations.get(MiriamType.ENTREZ), 0); -- GitLab