From 5e18be3ecac114d2d4a31ccd56271a7b6f1f0bc7 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Thu, 1 Jun 2017 15:10:10 +0200
Subject: [PATCH] new version of rest API for reactions

---
 README.md                                     |   7 +
 .../java/lcsb/mapviewer/api/BaseRestImpl.java |  64 ++++++
 .../api/projects/ProjectController.java       |   7 -
 .../api/projects/ProjectRestImpl.java         | 199 ------------------
 .../elements/ElementsController.java          |  12 +-
 .../elements/ElementsRestImpl.java            |  36 +---
 .../reactions/ReactionsController.java        |  35 +++
 .../reactions/ReactionsRestImpl.java          | 198 +++++++++++++++++
 .../resources/applicationContext-rest.xml     |   1 +
 .../services/impl/ReferenceGenomeService.java |   5 -
 10 files changed, 316 insertions(+), 248 deletions(-)
 create mode 100644 rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java
 create mode 100644 rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java

diff --git a/README.md b/README.md
index 0e2c0ac693..4617a0f21d 100644
--- a/README.md
+++ b/README.md
@@ -21,5 +21,12 @@ Rest API tries to follow [API Design Guide](https://cloud.google.com/apis/design
       * `columns` - set of columns. Possible values are: id, modelId, name, type, description, symbol, complexId, compartmentId, fullName, abbreviation, formula, name, synonyms, formerSymbols, references, bounds, hierarchyVisibilityLevel,
       * `ids` - set of database ids 
     * Example: `/projects/pdmap_feb17/bioEntities/elements/?columns=id,name,type`
+* Reactions:
+    * URL: `/projects/{projectId}/bioEntities/reactions/`
+    * Method: GET
+    * Parameters:
+      * `columns` - set of columns. Possible values are: 
+      * `ids` - set of database ids 
+    * Example: `/projects/pdmap_feb17/bioEntities/reactions/?columns=id,name,type`
 ### Users
 ### Configuration
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java
index 82a8400836..8cfea323f1 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseRestImpl.java
@@ -1,14 +1,29 @@
 package lcsb.mapviewer.api;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
 import lcsb.mapviewer.common.exception.InvalidStateException;
+import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.Element;
+import lcsb.mapviewer.services.SecurityException;
+import lcsb.mapviewer.services.interfaces.IModelService;
+import lcsb.mapviewer.services.interfaces.IUserService;
 import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
 
+@Transactional(value = "txManager")
 public abstract class BaseRestImpl {
+	@Autowired
+	private IModelService	modelService;
+	@Autowired
+	private IUserService	userService;
+
 	protected Map<String, Object> okStatus() {
 		Map<String, Object> result = new HashMap<>();
 		result.put("status", "OK");
@@ -34,4 +49,53 @@ public abstract class BaseRestImpl {
 		return result;
 	};
 
+	protected List<Model> getModels(String projectId, String modelId, String token) throws SecurityException {
+		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
+		List<Model> models = new ArrayList<>();
+
+		if (!modelId.equals("*")) {
+			for (String str : modelId.split(",")) {
+				models.add(model.getSubmodelById(Integer.valueOf(str)));
+			}
+		} else {
+			models.addAll(model.getSubmodels());
+			models.add(model);
+		}
+		return models;
+	}
+
+	/**
+	 * @return the modelService
+	 * @see #modelService
+	 */
+	public IModelService getModelService() {
+		return modelService;
+	}
+
+	/**
+	 * @param modelService
+	 *          the modelService to set
+	 * @see #modelService
+	 */
+	public void setModelService(IModelService modelService) {
+		this.modelService = modelService;
+	}
+
+	/**
+	 * @return the userService
+	 * @see #userService
+	 */
+	public IUserService getUserService() {
+		return userService;
+	}
+
+	/**
+	 * @param userService
+	 *          the userService to set
+	 * @see #userService
+	 */
+	public void setUserService(IUserService userService) {
+		this.userService = userService;
+	}
+
 }
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java
index 295e33e676..5ce7802b5d 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectController.java
@@ -41,13 +41,6 @@ public class ProjectController extends BaseController {
 		return projectController.getSuggestedQueryList(projectId, token);
 	}
 
-	@RequestMapping(value = "/project/getReactions", method = { RequestMethod.GET, RequestMethod.POST }, produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getReactions(@RequestParam(value = "projectId") String projectId, @RequestParam(value = "id", defaultValue = "") String id,
-			@RequestParam(value = "columns", defaultValue = "") String columns, @RequestParam(value = "token") String token,
-			@RequestParam(value = "participantId", defaultValue = "") String participantId) throws SecurityException {
-		return projectController.getReactions(projectId, id, columns, token, participantId);
-	}
-
 	@RequestMapping(value = "/project/getClosestElementsByCoordinates", method = { RequestMethod.GET, RequestMethod.POST },
 			produces = { MediaType.APPLICATION_JSON_VALUE })
 	public List<Map<String, Object>> getClosestElementsByCoordinates(@RequestParam(value = "projectId") String projectId,
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
index 55fe29eb11..882b991bf9 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/ProjectRestImpl.java
@@ -3,7 +3,6 @@ package lcsb.mapviewer.api.projects;
 import java.awt.geom.Path2D;
 import java.awt.geom.PathIterator;
 import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -19,7 +18,6 @@ import java.util.SortedMap;
 import java.util.TreeMap;
 
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -57,12 +55,8 @@ import lcsb.mapviewer.model.map.layout.Layout;
 import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.model.map.model.ModelData;
 import lcsb.mapviewer.model.map.model.ModelSubmodelConnection;
-import lcsb.mapviewer.model.map.reaction.Modifier;
-import lcsb.mapviewer.model.map.reaction.Product;
-import lcsb.mapviewer.model.map.reaction.Reactant;
 import lcsb.mapviewer.model.map.reaction.Reaction;
 import lcsb.mapviewer.model.map.species.Element;
-import lcsb.mapviewer.model.map.species.Species;
 import lcsb.mapviewer.model.user.User;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.UserAccessException;
@@ -72,7 +66,6 @@ import lcsb.mapviewer.services.interfaces.IProjectService;
 import lcsb.mapviewer.services.interfaces.ISearchService;
 import lcsb.mapviewer.services.interfaces.IUserService;
 import lcsb.mapviewer.services.search.data.ElementIdentifier.ElementIdentifierType;
-import lcsb.mapviewer.services.search.data.LightReactionView;
 import lcsb.mapviewer.services.utils.ColorSchemaReader;
 import lcsb.mapviewer.services.utils.data.BuildInLayout;
 import lcsb.mapviewer.services.utils.gmap.CoordinationConverter;
@@ -258,198 +251,6 @@ public class ProjectRestImpl {
 		return result;
 	};
 
-	public List<Map<String, Object>> getReactions(String projectId, String id, String columns, String token, String participantElementId)
-			throws UserAccessException, SecurityException {
-		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
-		Set<Integer> ids = new HashSet<>();
-		if (!id.equals("")) {
-			for (String str : id.split(",")) {
-				ids.add(Integer.valueOf(str));
-			}
-		}
-		Set<Element> elementSet = new HashSet<>();
-		if (!participantElementId.equals("")) {
-			for (String str : participantElementId.split(",")) {
-				elementSet.add(model.getElementByDbId(Integer.valueOf(str)));
-			}
-		}
-		Set<String> columnsSet = createReactionColumnSet(columns);
-
-		List<Map<String, Object>> result = new ArrayList<>();
-
-		List<Model> models = new ArrayList<>();
-		models.addAll(model.getSubmodels());
-		models.add(model);
-		for (Model model2 : models) {
-			for (Reaction reaction : model2.getReactions()) {
-				if (ids.size() == 0 || ids.contains(reaction.getId())) {
-					if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) {
-						result.add(preparedReaction(reaction, columnsSet));
-					}
-				}
-			}
-		}
-
-		return result;
-	}
-
-	private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) {
-		for (Element element : elementSet) {
-			if (reaction.containsElement(element)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) {
-		Map<String, Object> result = new HashMap<>();
-		for (String string : columnsSet) {
-			String column = string.toLowerCase();
-			Object value = null;
-			if (column.equals("id") || column.equals("idobject")) {
-				value = reaction.getId();
-			} else if (column.equals("modelid")) {
-				value = reaction.getModelData().getId();
-			} else if (column.equals("reactionid")) {
-				value = reaction.getIdReaction();
-			} else if (column.equals("name")) {
-				value = reaction.getName();
-			} else if (column.equals("centerpoint")) {
-				value = reaction.getCenterPoint();
-			} else if (column.equals("products")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Product product : reaction.getProducts()) {
-					ids.add(product.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("reactants")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Reactant reactant : reaction.getReactants()) {
-					ids.add(reactant.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("modifiers")) {
-				List<Integer> ids = new ArrayList<>();
-				for (Modifier product : reaction.getModifiers()) {
-					ids.add(product.getElement().getId());
-				}
-				value = StringUtils.join(ids, ",");
-			} else if (column.equals("type")) {
-				value = reaction.getStringType();
-			} else if (column.equals("hierarchyvisibilitylevel")) {
-				value = reaction.getVisibilityLevel();
-			} else if (column.equals("lines")) {
-				value = new LightReactionView(reaction).getLines();
-			} else {
-				value = "Unknown column";
-			}
-			result.put(string, value);
-		}
-		return result;
-	}
-
-	private Map<String, Object> preparedElement(Element element, Set<String> columnsSet) {
-		Map<String, Object> result = new HashMap<>();
-		for (String string : columnsSet) {
-			String column = string.toLowerCase();
-			Object value = null;
-			if (column.equals("id") || column.equals("idobject")) {
-				value = element.getId();
-			} else if (column.equals("modelid")) {
-				value = element.getModelData().getId();
-			} else if (column.equals("name")) {
-				value = element.getName();
-			} else if (column.equals("type")) {
-				value = element.getStringType();
-			} else if (column.equals("symbol")) {
-				value = element.getSymbol();
-			} else if (column.equals("fullname")) {
-				value = element.getFullName();
-			} else if (column.equals("abbreviation")) {
-				value = element.getAbbreviation();
-			} else if (column.equals("compartmentid")) {
-				if (element.getCompartment() != null) {
-					value = element.getCompartment().getId();
-				}
-			} else if (column.equals("complexid")) {
-				if (element instanceof Species) {
-					if (((Species) element).getComplex() != null) {
-						value = ((Species) element).getComplex().getId();
-					}
-				}
-			} else if (column.equals("references")) {
-				value = annotationViewFactory.createList(element.getMiriamData());
-			} else if (column.equals("synonyms")) {
-				value = element.getSynonyms();
-			} else if (column.equals("formula")) {
-				value = element.getFormula();
-			} else if (column.equals("description")) {
-				value = element.getNotes();
-			} else if (column.equals("formersymbols")) {
-				value = element.getFormerSymbols();
-			} else if (column.equals("hierarchyvisibilitylevel")) {
-				value = element.getVisibilityLevel();
-			} else if (column.equals("bounds")) {
-				value = new Rectangle2D.Double(element.getX(), element.getY(), element.getWidth(), element.getHeight());
-			} else {
-				value = "Unknown column";
-			}
-			result.put(string, value);
-		}
-		return result;
-	}
-
-	private Set<String> createElementColumnSet(String columns) {
-		Set<String> columnsSet = new HashSet<>();
-		if (columns.equals("")) {
-			columnsSet.add("id");
-			columnsSet.add("modelId");
-			columnsSet.add("name");
-			columnsSet.add("type");
-			columnsSet.add("description");
-			columnsSet.add("type");
-			columnsSet.add("symbol");
-			columnsSet.add("complexId");
-			columnsSet.add("compartmentId");
-			columnsSet.add("fullName");
-			columnsSet.add("abbreviation");
-			columnsSet.add("formula");
-			columnsSet.add("name");
-			columnsSet.add("synonyms");
-			columnsSet.add("formerSymbols");
-			columnsSet.add("references");
-			columnsSet.add("bounds");
-			columnsSet.add("hierarchyVisibilityLevel");
-		} else {
-			for (String str : columns.split(",")) {
-				columnsSet.add(str);
-			}
-		}
-		return columnsSet;
-	}
-
-	private Set<String> createReactionColumnSet(String columns) {
-		Set<String> columnsSet = new HashSet<>();
-		if (columns.equals("")) {
-			columnsSet.add("id");
-			columnsSet.add("reactionId");
-			columnsSet.add("modelId");
-			columnsSet.add("type");
-			columnsSet.add("lines");
-			columnsSet.add("centerPoint");
-			columnsSet.add("products");
-			columnsSet.add("reactants");
-			columnsSet.add("modifiers");
-			columnsSet.add("hierarchyVisibilityLevel");
-		} else {
-			for (String str : columns.split(",")) {
-				columnsSet.add(str);
-			}
-		}
-		return columnsSet;
-	}
-
 	/**
 	 * @return the modelService
 	 * @see #modelService
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java
index ee7b732401..d006a63c73 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsController.java
@@ -19,11 +19,15 @@ public class ElementsController extends BaseController {
 	@Autowired
 	private ElementsRestImpl projectController;
 
-	@RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/elements/", method = { RequestMethod.GET},
+	@RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/elements/", method = { RequestMethod.GET },
 			produces = { MediaType.APPLICATION_JSON_VALUE })
-	public List<Map<String, Object>> getElements(@PathVariable(value = "projectId") String projectId, @PathVariable(value = "modelId") String modelId,
-			@RequestParam(value = "id", defaultValue = "") String id, @RequestParam(value = "columns", defaultValue = "") String columns,
-			@RequestParam(value = "token") String token) throws SecurityException {
+	public List<Map<String, Object>> getElements(//
+			@PathVariable(value = "projectId") String projectId, //
+			@PathVariable(value = "modelId") String modelId, //
+			@RequestParam(value = "id", defaultValue = "") String id, //
+			@RequestParam(value = "columns", defaultValue = "") String columns, //
+			@RequestParam(value = "token") String token//
+	) throws SecurityException {
 		return projectController.getElements(projectId, id, columns, modelId, token);
 	}
 
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java
index d34fc6e610..6336c0e0a8 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/elements/ElementsRestImpl.java
@@ -12,24 +12,21 @@ import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
+import lcsb.mapviewer.api.BaseRestImpl;
 import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.model.map.species.Species;
 import lcsb.mapviewer.services.SecurityException;
 import lcsb.mapviewer.services.UserAccessException;
 import lcsb.mapviewer.services.interfaces.IModelService;
-import lcsb.mapviewer.services.interfaces.IUserService;
 import lcsb.mapviewer.services.view.AnnotationViewFactory;
 import lcsb.mapviewer.services.view.OverviewImageViewFactory;
 
 @Transactional(value = "txManager")
-public class ElementsRestImpl {
+public class ElementsRestImpl extends BaseRestImpl {
 
 	Logger													 logger	= Logger.getLogger(ElementsRestImpl.class);
 
-	@Autowired
-	private IUserService						 userService;
-
 	@Autowired
 	private IModelService						 modelService;
 
@@ -39,26 +36,8 @@ public class ElementsRestImpl {
 	@Autowired
 	private OverviewImageViewFactory factory;
 
-	/**
-	 * @return the userService
-	 * @see #userService
-	 */
-	public IUserService getUserService() {
-		return userService;
-	}
-
-	/**
-	 * @param userService
-	 *          the userService to set
-	 * @see #userService
-	 */
-	public void setUserService(IUserService userService) {
-		this.userService = userService;
-	}
-
 	public List<Map<String, Object>> getElements(String projectId, String id, String columns, String modelId, String token)
 			throws UserAccessException, SecurityException {
-		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
 		Set<Integer> ids = new HashSet<>();
 		if (!id.equals("")) {
 			for (String str : id.split(",")) {
@@ -69,16 +48,7 @@ public class ElementsRestImpl {
 
 		List<Map<String, Object>> result = new ArrayList<>();
 
-		List<Model> models = new ArrayList<>();
-
-		if (!modelId.equals("*")) {
-			for (String str : modelId.split(",")) {
-				models.add(model.getSubmodelById(Integer.valueOf(str)));
-			}
-		} else {
-			models.addAll(model.getSubmodels());
-			models.add(model);
-		}
+		List<Model> models = getModels(projectId, modelId, token);
 
 		for (Model model2 : models) {
 			for (Element element : model2.getElements()) {
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java
new file mode 100644
index 0000000000..342e044466
--- /dev/null
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsController.java
@@ -0,0 +1,35 @@
+package lcsb.mapviewer.api.projects.models.bioEntities.reactions;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import lcsb.mapviewer.api.BaseController;
+import lcsb.mapviewer.services.SecurityException;
+
+@RestController
+public class ReactionsController extends BaseController {
+	@Autowired
+	private ReactionsRestImpl reactionController;
+
+	@RequestMapping(value = "/projects/{projectId}/models/{modelId}/bioEntities/reactions/", method = { RequestMethod.GET },
+			produces = { MediaType.APPLICATION_JSON_VALUE })
+	public List<Map<String, Object>> getReactions(//
+			@PathVariable(value = "projectId") String projectId, //
+			@PathVariable(value = "modelId") String modelId,
+			@RequestParam(value = "id", defaultValue = "") String id, //
+			@RequestParam(value = "columns", defaultValue = "") String columns, //
+			@RequestParam(value = "token") String token, //
+			@RequestParam(value = "participantId", defaultValue = "") String participantId//
+	) throws SecurityException {
+		return reactionController.getReactions(projectId, id, columns, modelId,  token, participantId);
+	}
+
+}
\ No newline at end of file
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java
new file mode 100644
index 0000000000..64bd74ad1f
--- /dev/null
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/bioEntities/reactions/ReactionsRestImpl.java
@@ -0,0 +1,198 @@
+package lcsb.mapviewer.api.projects.models.bioEntities.reactions;
+
+import java.awt.geom.PathIterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.reaction.Modifier;
+import lcsb.mapviewer.model.map.reaction.Product;
+import lcsb.mapviewer.model.map.reaction.Reactant;
+import lcsb.mapviewer.model.map.reaction.Reaction;
+import lcsb.mapviewer.model.map.species.Element;
+import lcsb.mapviewer.services.SecurityException;
+import lcsb.mapviewer.services.UserAccessException;
+import lcsb.mapviewer.services.interfaces.IModelService;
+import lcsb.mapviewer.services.interfaces.IUserService;
+import lcsb.mapviewer.services.search.data.LightReactionView;
+import lcsb.mapviewer.services.view.AnnotationViewFactory;
+
+@Transactional(value = "txManager")
+public class ReactionsRestImpl {
+
+	/**
+	 * Constant defining size of the array returned by
+	 * {@link PathIterator#currentSegment(double[])} method. More nformation can
+	 * be found <a href=
+	 * "http://docs.oracle.com/javase/7/docs/api/java/awt/geom/PathIterator.html#currentSegment(double[])"
+	 * >here</a>
+	 */
+	private static final int PATH_ITERATOR_SEGMENT_SIZE	= 6;
+
+	Logger									 logger											= Logger.getLogger(ReactionsRestImpl.class);
+
+	@Autowired
+	private IUserService		 userService;
+
+	@Autowired
+	private IModelService		 modelService;
+
+	@Autowired
+	AnnotationViewFactory		 annotationViewFactory;
+
+	/**
+	 * @return the userService
+	 * @see #userService
+	 */
+	public IUserService getUserService() {
+		return userService;
+	}
+
+	/**
+	 * @param userService
+	 *          the userService to set
+	 * @see #userService
+	 */
+	public void setUserService(IUserService userService) {
+		this.userService = userService;
+	}
+
+	public List<Map<String, Object>> getReactions(String projectId, String id, String columns, String modelId, String token, String participantElementId)
+			throws UserAccessException, SecurityException {
+		Model model = modelService.getLastModelByProjectId(projectId, userService.getToken(token));
+		Set<Integer> ids = new HashSet<>();
+		if (!id.equals("")) {
+			for (String str : id.split(",")) {
+				ids.add(Integer.valueOf(str));
+			}
+		}
+		Set<Element> elementSet = new HashSet<>();
+		if (!participantElementId.equals("")) {
+			for (String str : participantElementId.split(",")) {
+				elementSet.add(model.getElementByDbId(Integer.valueOf(str)));
+			}
+		}
+		Set<String> columnsSet = createReactionColumnSet(columns);
+
+		List<Map<String, Object>> result = new ArrayList<>();
+
+		List<Model> models = new ArrayList<>();
+		models.addAll(model.getSubmodels());
+		models.add(model);
+		for (Model model2 : models) {
+			for (Reaction reaction : model2.getReactions()) {
+				if (ids.size() == 0 || ids.contains(reaction.getId())) {
+					if (elementSet.size() == 0 || reactionContainsElement(reaction, elementSet)) {
+						result.add(preparedReaction(reaction, columnsSet));
+					}
+				}
+			}
+		}
+
+		return result;
+	}
+
+	private boolean reactionContainsElement(Reaction reaction, Set<Element> elementSet) {
+		for (Element element : elementSet) {
+			if (reaction.containsElement(element)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private Map<String, Object> preparedReaction(Reaction reaction, Set<String> columnsSet) {
+		Map<String, Object> result = new HashMap<>();
+		for (String string : columnsSet) {
+			String column = string.toLowerCase();
+			Object value = null;
+			if (column.equals("id") || column.equals("idobject")) {
+				value = reaction.getId();
+			} else if (column.equals("modelid")) {
+				value = reaction.getModelData().getId();
+			} else if (column.equals("reactionid")) {
+				value = reaction.getIdReaction();
+			} else if (column.equals("name")) {
+				value = reaction.getName();
+			} else if (column.equals("centerpoint")) {
+				value = reaction.getCenterPoint();
+			} else if (column.equals("products")) {
+				List<Integer> ids = new ArrayList<>();
+				for (Product product : reaction.getProducts()) {
+					ids.add(product.getElement().getId());
+				}
+				value = StringUtils.join(ids, ",");
+			} else if (column.equals("reactants")) {
+				List<Integer> ids = new ArrayList<>();
+				for (Reactant reactant : reaction.getReactants()) {
+					ids.add(reactant.getElement().getId());
+				}
+				value = StringUtils.join(ids, ",");
+			} else if (column.equals("modifiers")) {
+				List<Integer> ids = new ArrayList<>();
+				for (Modifier product : reaction.getModifiers()) {
+					ids.add(product.getElement().getId());
+				}
+				value = StringUtils.join(ids, ",");
+			} else if (column.equals("type")) {
+				value = reaction.getStringType();
+			} else if (column.equals("hierarchyvisibilitylevel")) {
+				value = reaction.getVisibilityLevel();
+			} else if (column.equals("lines")) {
+				value = new LightReactionView(reaction).getLines();
+			} else {
+				value = "Unknown column";
+			}
+			result.put(string, value);
+		}
+		return result;
+	}
+
+	private Set<String> createReactionColumnSet(String columns) {
+		Set<String> columnsSet = new HashSet<>();
+		if (columns.equals("")) {
+			columnsSet.add("id");
+			columnsSet.add("reactionId");
+			columnsSet.add("modelId");
+			columnsSet.add("type");
+			columnsSet.add("lines");
+			columnsSet.add("centerPoint");
+			columnsSet.add("products");
+			columnsSet.add("reactants");
+			columnsSet.add("modifiers");
+			columnsSet.add("hierarchyVisibilityLevel");
+		} else {
+			for (String str : columns.split(",")) {
+				columnsSet.add(str);
+			}
+		}
+		return columnsSet;
+	}
+
+	/**
+	 * @return the modelService
+	 * @see #modelService
+	 */
+	public IModelService getModelService() {
+		return modelService;
+	}
+
+	/**
+	 * @param modelService
+	 *          the modelService to set
+	 * @see #modelService
+	 */
+	public void setModelService(IModelService modelService) {
+		this.modelService = modelService;
+	}
+
+}
diff --git a/rest-api/src/main/resources/applicationContext-rest.xml b/rest-api/src/main/resources/applicationContext-rest.xml
index 3d406d92d3..5bcd700f1b 100644
--- a/rest-api/src/main/resources/applicationContext-rest.xml
+++ b/rest-api/src/main/resources/applicationContext-rest.xml
@@ -20,6 +20,7 @@
 
 	<bean id="ProjectRestImpl" class="lcsb.mapviewer.api.projects.ProjectRestImpl"/>
 	<bean id="ElementsRestImpl" class="lcsb.mapviewer.api.projects.models.bioEntities.elements.ElementsRestImpl"/>
+	<bean id="ReactionsRestImpl" class="lcsb.mapviewer.api.projects.models.bioEntities.reactions.ReactionsRestImpl"/>
 
 	<bean id="ReferenceGenomeRestImpl" class="lcsb.mapviewer.api.genomics.ReferenceGenomeRestImpl"/>
 	<bean id="UserRestImpl" class="lcsb.mapviewer.api.controller.UserRestImpl"/>
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java
index c17dc5ebcd..666eda198c 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/ReferenceGenomeService.java
@@ -136,11 +136,6 @@ public class ReferenceGenomeService implements IReferenceGenomeService {
 	public ReferenceGenomeView getReferenceGenomeViewByParams(MiriamData miriamData, ReferenceGenomeType genomeType, String version) {
 		List<ReferenceGenome> list = referenceGenomeDao.getByType(genomeType);
 		for (ReferenceGenome referenceGenome : list) {
-			logger.debug(referenceGenome.getOrganism());
-			logger.debug(referenceGenome.getVersion());
-			logger.debug("---");
-			logger.debug(miriamData);
-			logger.debug(version);
 			if (referenceGenome.getOrganism().equals(miriamData) && referenceGenome.getVersion().equals(version)) {
 				return factory.create(referenceGenome);
 			}
-- 
GitLab