From b806fc06bf17acd8ce461d49403c7592741297eb Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Fri, 20 Jan 2017 14:53:07 +0100
Subject: [PATCH] mirna api

---
 .../mapviewer/api/mirna/MiRnaController.java  |  38 +++
 .../mapviewer/api/mirna/MiRnaRestImpl.java    | 269 ++++++++++++++++++
 .../resources/applicationContext-rest.xml     |   1 +
 3 files changed, 308 insertions(+)
 create mode 100644 rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java
 create mode 100644 rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java

diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java b/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java
new file mode 100644
index 0000000000..46ec8084bf
--- /dev/null
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaController.java
@@ -0,0 +1,38 @@
+package lcsb.mapviewer.api.mirna;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import lcsb.mapviewer.api.BaseController;
+import lcsb.mapviewer.api.QueryException;
+import lcsb.mapviewer.services.SecurityException;
+
+@RestController
+@RequestMapping("/miRna")
+public class MiRnaController extends BaseController {
+
+	@Autowired
+	private MiRnaRestImpl miRnaController;
+
+	@RequestMapping(value = "/getMiRnasByQuery", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+	public List<Map<String, Object>> getMiRnasByQuery(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId,
+			@RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "query") String query)
+			throws SecurityException, QueryException {
+		return miRnaController.getMiRnasByQuery(token, projectId, columns, query);
+	}
+
+	@RequestMapping(value = "/getMiRnasByTarget", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
+	public List<Map<String, Object>> getMiRnasByTarget(@RequestParam(value = "token") String token, @RequestParam(value = "projectId") String projectId,
+			@RequestParam(value = "targetType", defaultValue = "ALIAS") String targetType, @RequestParam(value = "targetId", defaultValue = "") String targetId,
+			@RequestParam(value = "columns", defaultValue = "") String columns) throws SecurityException, QueryException {
+		return miRnaController.getMiRnasByTarget(token, projectId, targetType, targetId, columns);
+	}
+
+}
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java
new file mode 100644
index 0000000000..9041e2d848
--- /dev/null
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/mirna/MiRnaRestImpl.java
@@ -0,0 +1,269 @@
+package lcsb.mapviewer.api.mirna;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import lcsb.mapviewer.annotation.services.TaxonomyBackend;
+import lcsb.mapviewer.api.QueryException;
+import lcsb.mapviewer.common.exception.InvalidArgumentException;
+import lcsb.mapviewer.model.Project;
+import lcsb.mapviewer.model.map.AnnotatedObject;
+import lcsb.mapviewer.model.map.MiriamData;
+import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.reaction.Reaction;
+import lcsb.mapviewer.model.map.species.Element;
+import lcsb.mapviewer.services.SecurityException;
+import lcsb.mapviewer.services.interfaces.IModelService;
+import lcsb.mapviewer.services.interfaces.IUserService;
+import lcsb.mapviewer.services.search.ElementMatcher;
+import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
+import lcsb.mapviewer.services.search.db.DbSearchCriteria;
+import lcsb.mapviewer.services.search.db.GeneRow;
+import lcsb.mapviewer.services.search.db.TargetView;
+import lcsb.mapviewer.services.search.db.mirna.IMiRNAService;
+import lcsb.mapviewer.services.search.db.mirna.MiRNAView;
+import lcsb.mapviewer.services.view.AnnotationView;
+import lcsb.mapviewer.services.view.AuthenticationToken;
+
+@Transactional(value = "txManager")
+public class MiRnaRestImpl {
+
+	Logger									 logger	= Logger.getLogger(MiRnaRestImpl.class);
+
+	@Autowired
+	private IMiRNAService miRnaService;
+
+	@Autowired
+	private IModelService		 modelService;
+
+	@Autowired
+	private IUserService		 userService;
+
+	@Autowired
+	private ElementMatcher	 elementMatcher;
+
+	public List<Map<String, Object>> getMiRnasByQuery(String token, String projectId, String columns, String query) throws SecurityException, QueryException {
+		AuthenticationToken authenticationToken = userService.getToken(token);
+		Model model = modelService.getLastModelByProjectId(projectId, authenticationToken);
+		if (model == null) {
+			throw new QueryException("Project with given id doesn't exist");
+		}
+		Project project = model.getProject();
+		if (project.getDisease() == null) {
+			throw new QueryException("Project doesn't have disease associated to it");
+		}
+
+		Set<String> columnSet = createMiRnaColumnSet(columns);
+
+		List<Map<String, Object>> result = new ArrayList<>();
+
+		MiriamData organism = project.getOrganism();
+		if (organism == null) {
+			organism = TaxonomyBackend.HUMAN_TAXONOMY;
+		}
+		MiRNAView miRna = miRnaService.getByName(query, new DbSearchCriteria().model(model).organisms(organism).colorSet(0).disease(project.getDisease()));
+		if (miRna != null) {
+			List<Model> models = getModels(model);
+			result.add(prepareMiRna(miRna, columnSet, models));
+		}
+
+		return result;
+	}
+
+	private List<Model> getModels(Model model) {
+		List<Model> models = new ArrayList<>();
+		models.add(model);
+		models.addAll(model.getSubmodels());
+		return models;
+	}
+
+	/**
+	 * @return the userService
+	 * @see #userService
+	 */
+	public IUserService getUserService() {
+		return userService;
+	}
+
+	/**
+	 * @param userService
+	 *          the userService to set
+	 * @see #userService
+	 */
+	public void setUserService(IUserService userService) {
+		this.userService = userService;
+	}
+
+	/**
+	 * @return the modelService
+	 * @see #modelService
+	 */
+	public IModelService getModelService() {
+		return modelService;
+	}
+
+	/**
+	 * @param modelService
+	 *          the modelService to set
+	 * @see #modelService
+	 */
+	public void setModelService(IModelService modelService) {
+		this.modelService = modelService;
+	}
+
+	private Map<String, Object> prepareMiRna(MiRNAView miRna, Set<String> columnsSet, List<Model> models) {
+		Map<String, Object> result = new HashMap<>();
+		for (String string : columnsSet) {
+			String column = string.toLowerCase();
+			Object value = null;
+			if (column.equals("id") || column.equals("idobject")) {
+				value = miRna.getUniqueId();
+			} else if (column.equals("name")) {
+				value = miRna.getName();
+			} else if (column.equals("targets")) {
+				value = prepareTargets(miRna.getTargetRows(), models);
+			} else {
+				value = "Unknown column";
+			}
+			result.put(string, value);
+		}
+		return result;
+	}
+
+	private List<Map<String, Object>> prepareTargets(Collection<TargetView> targets, List<Model> models) {
+		List<Map<String, Object>> result = new ArrayList<>();
+		for (TargetView target : targets) {
+			result.add(prepareTarget(target, models));
+		}
+		return result;
+	}
+
+	private Map<String, Object> prepareTarget(TargetView target, List<Model> models) {
+		Map<String, Object> result = new HashMap<>();
+		result.put("name", target.getName());
+		result.put("references", target.getReferences());
+		List<AnnotationView> participants = new ArrayList<>();
+		for (GeneRow row : target.getProteins()) {
+			participants.add(row.getAnnotation());
+		}
+		result.put("targetParticipants", participants);
+
+		List<Map<String, Object>> targetedObjects = new ArrayList<>();
+		for (Model model : models) {
+			for (AnnotatedObject object : model.getAnnotatedObjects()) {
+				if (elementMatcher.elementMatch(target, object)) {
+					Map<String, Object> elementMapping = new HashMap<>();
+
+					elementMapping.put("id", object.getId());
+					elementMapping.put("type", getType(object));
+					elementMapping.put("modelId", model.getId());
+					targetedObjects.add(elementMapping);
+				}
+			}
+		}
+
+		result.put("targetElements", targetedObjects);
+
+		return result;
+	}
+
+	private String getType(AnnotatedObject object) {
+		if (object instanceof Reaction) {
+			return ElementIdentifierType.REACTION.getJsName();
+		} else if (object instanceof Element) {
+			return ElementIdentifierType.ALIAS.getJsName();
+		} else {
+			throw new InvalidArgumentException("Unknown type of element " + object.getClass());
+		}
+	}
+
+	private Set<String> createMiRnaColumnSet(String columns) {
+		Set<String> columnsSet = new HashSet<>();
+		if (columns.equals("")) {
+			columnsSet.add("name");
+			columnsSet.add("id");
+			columnsSet.add("targets");
+		} else {
+			for (String str : columns.split(",")) {
+				columnsSet.add(str);
+			}
+		}
+		return columnsSet;
+	}
+
+	/**
+	 * @return the miRnaService
+	 * @see #miRnaService
+	 */
+	public IMiRNAService getMiRnaService() {
+		return miRnaService;
+	}
+
+	/**
+	 * @param miRnaService
+	 *          the miRnaService to set
+	 * @see #miRnaService
+	 */
+	public void setMiRnaService(IMiRNAService miRnaService) {
+		this.miRnaService = miRnaService;
+	}
+
+	public List<Map<String, Object>> getMiRnasByTarget(String token, String projectId, String targetType, String targetId, String columns)
+			throws SecurityException, QueryException {
+		AuthenticationToken authenticationToken = userService.getToken(token);
+		Model model = modelService.getLastModelByProjectId(projectId, authenticationToken);
+		if (model == null) {
+			throw new QueryException("Project with given id doesn't exist");
+		}
+		Project project = model.getProject();
+
+		if (project.getDisease() == null) {
+			throw new QueryException("Project doesn't have disease associated to it");
+		}
+
+		Integer dbId = Integer.valueOf(targetId);
+		List<Element> targets = new ArrayList<>();
+		if (targetType.equals(ElementIdentifierType.ALIAS.getJsName())) {
+			Element element = model.getElementByDbId(dbId);
+			for (Model m : model.getSubmodels()) {
+				if (element == null) {
+					element = m.getElementByDbId(dbId);
+				}
+			}
+			if (element == null) {
+				throw new QueryException("Invalid element identifier for given project");
+			}
+			targets.add(element);
+		} else {
+			throw new QueryException("Targeting for the type not implemented");
+		}
+		MiriamData organism = project.getOrganism();
+		if (organism == null) {
+			organism = TaxonomyBackend.HUMAN_TAXONOMY;
+		}
+
+		Set<String> columnSet = createMiRnaColumnSet(columns);
+
+		List<MiRNAView> miRnas = miRnaService.getForTargets(targets, new DbSearchCriteria().model(model).organisms(organism).disease(project.getDisease()));
+
+		List<Map<String, Object>> result = new ArrayList<>();
+
+		List<Model> models = getModels(model);
+
+		for (MiRNAView miRna : miRnas) {
+			result.add(prepareMiRna(miRna, columnSet, models));
+		}
+
+		return result;
+	}
+
+}
diff --git a/rest-api/src/main/resources/applicationContext-rest.xml b/rest-api/src/main/resources/applicationContext-rest.xml
index 935d23b1a9..d86f6e3c69 100644
--- a/rest-api/src/main/resources/applicationContext-rest.xml
+++ b/rest-api/src/main/resources/applicationContext-rest.xml
@@ -15,6 +15,7 @@
 	<bean id="ConfigurationRestImpl" class="lcsb.mapviewer.api.configuration.ConfigurationRestImpl"/>
 	<bean id="CommentRestImpl" class="lcsb.mapviewer.api.comment.CommentRestImpl"/>
 	<bean id="DrugRestImpl" class="lcsb.mapviewer.api.drug.DrugRestImpl"/>
+	<bean id="MiRnaRestImpl" class="lcsb.mapviewer.api.mirna.MiRnaRestImpl"/>
 	<bean id="OverlayRestImpl" class="lcsb.mapviewer.api.overlay.OverlayRestImpl"/>
 	<bean id="ProjectRestImpl" class="lcsb.mapviewer.api.project.ProjectRestImpl"/>
 	
-- 
GitLab