Commit 279ee560 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

publication API does not use old model cache

parent f999be16
......@@ -41,6 +41,7 @@
<spring-security-test.version>5.0.8.RELEASE</spring-security-test.version>
<springframework.webflow.version>2.5.1.RELEASE</springframework.webflow.version>
<springframework.boot.version>2.0.5.RELEASE</springframework.boot.version>
<spring.data.version>2.0.10.RELEASE</spring.data.version>
<spring.restdocs.version>2.0.3.RELEASE</spring.restdocs.version>
......
......@@ -26,7 +26,7 @@ public class PublicationsController extends BaseController {
public Map<String, Object> getPublications(
@PathVariable(value = "projectId") String projectId,
@PathVariable(value = "modelId") String modelId,
@RequestParam(value = "start", defaultValue = "0") String start,
@RequestParam(value = "page", defaultValue = "0") String start,
@RequestParam(value = "length", defaultValue = "10") Integer length,
@RequestParam(value = "sortColumn", defaultValue = "pubmedId") String sortColumn,
@RequestParam(value = "sortOrder", defaultValue = "asc") String sortOrder,
......
......@@ -7,6 +7,8 @@ import org.apache.commons.lang3.math.NumberUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -18,7 +20,12 @@ import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.model.Article;
import lcsb.mapviewer.model.map.*;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.model.ModelData;
import lcsb.mapviewer.persist.dao.ArticleProperty;
import lcsb.mapviewer.persist.dao.map.ReactionProperty;
import lcsb.mapviewer.persist.dao.map.species.ElementProperty;
import lcsb.mapviewer.services.QueryException;
import lcsb.mapviewer.services.interfaces.*;
@Transactional
@Service
......@@ -31,9 +38,19 @@ public class PublicationsRestImpl extends BaseRestImpl {
private PubmedParser pubmedParser;
private IPublicationService publicationService;
private IElementService elementService;;
private IReactionService reactionService;
@Autowired
public PublicationsRestImpl(PubmedParser pubmedParser) {
public PublicationsRestImpl(PubmedParser pubmedParser, IPublicationService publicationService,
IElementService elementService,
IReactionService reactionService) {
this.pubmedParser = pubmedParser;
this.publicationService = publicationService;
this.elementService = elementService;
this.reactionService = reactionService;
}
public SortedMap<MiriamData, List<BioEntity>> getPublications(Collection<Model> models) {
......@@ -57,176 +74,103 @@ public class PublicationsRestImpl extends BaseRestImpl {
}
public Map<String, Object> getPublications(
String projectId, String modelId, String startString, Integer length,
String projectId, String modelId, String pageString, Integer length,
String sortColumn, String sortOrder, String search) throws QueryException {
List<Model> models = getModels(projectId, modelId);
SortColumn sortColumnEnum = getSortOrderColumn(sortColumn);
Comparator<Map.Entry<MiriamData, List<BioEntity>>> comparator = getComparatorForColumn(sortColumnEnum, sortOrder);
int page = parseInteger(pageString, "page");
ArticleProperty sortProperty = extractSortColumn(sortColumn);
Pageable pageable;
if (sortProperty != null) {
pageable = PageRequest.of(page, length, Sort.by(Direction.fromString(sortOrder), sortProperty.name()));
} else {
pageable = PageRequest.of(page, length);
Integer start = Math.max(0, Integer.valueOf(startString));
List<Map<String, Object>> resultList = new ArrayList<>();
}
Map<ArticleProperty, Object> filterOptions = new HashMap<>();
SortedMap<MiriamData, List<BioEntity>> publications = getPublications(models);
List<Map.Entry<MiriamData, List<BioEntity>>> filteredList = new ArrayList<>();
List<ModelData> models = getModelService().getModelsByMapId(projectId, modelId);
filterOptions.put(ArticleProperty.MODEL, models);
long count = publicationService.getCountByFilter(pageable, filterOptions);
for (Map.Entry<MiriamData, List<BioEntity>> entry : publications.entrySet()) {
Set<Model> publicationModels = new LinkedHashSet<>();
for (BioEntity bioEntity : entry.getValue()) {
publicationModels.add(bioEntity.getModel());
}
if (isSearchResult(entry.getKey(), search, publicationModels)) {
filteredList.add(entry);
}
if (search != null && !search.trim().equals("")) {
filterOptions.put(ArticleProperty.TEXT, search);
}
if (comparator != null) {
filteredList.sort(comparator);
Page<Article> articles = publicationService.getByFilter(pageable, filterOptions);
List<MiriamData> mds = new ArrayList<>();
for (Article article : articles) {
mds.add(new MiriamData(MiriamType.PUBMED, article.getPubmedId()));
}
int index = 0;
for (Map.Entry<MiriamData, List<BioEntity>> entry : filteredList) {
if (index >= start && index < start + length) {
List<Object> elements = new ArrayList<>();
for (BioEntity object : entry.getValue()) {
elements.add(createMinifiedSearchResult(object));
}
Map<ElementProperty, List<? extends Object>> elementSearch = new HashMap<>();
elementSearch.put(ElementProperty.ANNOTATION, mds);
elementSearch.put(ElementProperty.MAP, models);
Map<String, Object> row = new TreeMap<>();
row.put("elements", elements);
row.put("publication", createAnnotation(entry.getKey()));
resultList.add(row);
}
index++;
}
List<BioEntity> bioEntities = new ArrayList<>();
bioEntities.addAll(elementService.getElementsByFilter(elementSearch));
Map<String, Object> result = new TreeMap<>();
result.put("data", resultList);
result.put("totalSize", publications.size());
result.put("filteredSize", filteredList.size());
result.put("start", start);
result.put("length", resultList.size());
return result;
}
Map<ReactionProperty, List<? extends Object>> reactionSearch = new HashMap<>();
elementSearch.put(ElementProperty.ANNOTATION, mds);
elementSearch.put(ElementProperty.MAP, models);
Comparator<Entry<MiriamData, List<BioEntity>>> getComparatorForColumn(SortColumn sortColumnEnum,
String sortOrder) {
final int orderFactor;
if (sortOrder.toLowerCase().equals("desc")) {
orderFactor = -1;
} else {
orderFactor = 1;
}
if (sortColumnEnum == null) {
return null;
} else if (sortColumnEnum.equals(SortColumn.PUBMED_ID)) {
return new Comparator<Map.Entry<MiriamData, List<BioEntity>>>() {
IntegerComparator integerComparator = new IntegerComparator();
bioEntities.addAll(reactionService.getReactionsByFilter(reactionSearch));
@Override
public int compare(Entry<MiriamData, List<BioEntity>> o1, Entry<MiriamData, List<BioEntity>> o2) {
Integer id1 = extractPubmedId(o1.getKey());
Integer id2 = extractPubmedId(o2.getKey());
return integerComparator.compare(id1, id2) * orderFactor;
List<Map<String, Object>> resultList = new ArrayList<>();
}
Map<MiriamData, List<BioEntity>> publications = new HashMap<>();
};
} else if (sortColumnEnum.equals(SortColumn.YEAR)) {
return (o1, o2) -> {
try {
Article article1 = getArticle(o1.getKey().getResource());
Article article2 = getArticle(o2.getKey().getResource());
return article1.getYear().compareTo(article2.getYear()) * orderFactor;
} catch (Exception e) {
logger.error("Problem with accessing article data ", e);
return 0;
}
};
} else if (sortColumnEnum.equals(SortColumn.JOURNAL)) {
return (o1, o2) -> {
try {
Article article1 = getArticle(o1.getKey().getResource());
Article article2 = getArticle(o2.getKey().getResource());
return article1.getJournal().compareTo(article2.getJournal()) * orderFactor;
} catch (Exception e) {
logger.error("Problem with accessing article data ", e);
return 0;
}
};
} else if (sortColumnEnum.equals(SortColumn.TITLE)) {
return (o1, o2) -> {
try {
Article article1 = getArticle(o1.getKey().getResource());
Article article2 = getArticle(o2.getKey().getResource());
return article1.getTitle().compareTo(article2.getTitle()) * orderFactor;
} catch (Exception e) {
logger.error("Problem with accessing article data ", e);
return 0;
for (BioEntity bioEntity : bioEntities) {
for (MiriamData md : bioEntity.getMiriamData()) {
if (md.getDataType().equals(MiriamType.PUBMED)) {
List<BioEntity> list = publications.computeIfAbsent(md, k -> new ArrayList<>());
list.add(bioEntity);
}
}
};
} else if (sortColumnEnum.equals(SortColumn.AUTHORS)) {
return (o1, o2) -> {
try {
Article article1 = getArticle(o1.getKey().getResource());
Article article2 = getArticle(o2.getKey().getResource());
return article1.getStringAuthors().compareTo(article2.getStringAuthors()) * orderFactor;
} catch (Exception e) {
logger.error("Problem with accessing article data ", e);
return 0;
}
};
} else {
throw new InvalidArgumentException("Unknown column type: " + sortColumnEnum);
}
}
private SortColumn getSortOrderColumn(String sortColumn) throws QueryException {
if (!sortColumn.isEmpty()) {
for (SortColumn type : SortColumn.values()) {
if (type.commonName.toLowerCase().equals(sortColumn.toLowerCase())) {
return type;
}
for (Article article : articles) {
List<Object> elements = new ArrayList<>();
for (BioEntity bioEntity : publications.computeIfAbsent(new MiriamData(MiriamType.PUBCHEM, article.getPubmedId()),
k -> new ArrayList<>())) {
elements.add(createMinifiedSearchResult(bioEntity));
}
throw new QueryException("Unknown sortColumn: " + sortColumn);
Map<String, Object> row = new TreeMap<>();
row.put("elements", elements);
Map<String, Object> articleEntry = new HashMap<>();
articleEntry.put("article", article);
row.put("publication", articleEntry);
resultList.add(row);
}
return null;
Map<String, Object> result = new TreeMap<>();
result.put("data", resultList);
result.put("totalSize", count);
result.put("filteredSize", articles.getTotalElements());
result.put("page", page);
result.put("length", resultList.size());
return result;
}
private boolean isSearchResult(MiriamData key, String search, Set<Model> models) {
String lowerCaseSearch = search.toLowerCase();
if (search.isEmpty()) {
return true;
}
Article article = null;
if (MiriamType.PUBMED.equals(key.getDataType())) {
try {
article = pubmedParser.getPubmedArticleById(Integer.valueOf(key.getResource()));
} catch (PubmedSearchException e) {
logger.error("Problem with accessing info about pubmed", e);
}
private ArticleProperty extractSortColumn(String sortColumn) throws QueryException {
if (sortColumn == null) {
return null;
}
if (article != null) {
if (article.getPubmedId().toLowerCase().contains(lowerCaseSearch)) {
return true;
} else if (article.getJournal().toLowerCase().contains(lowerCaseSearch)) {
return true;
} else if (article.getStringAuthors().toLowerCase().contains(lowerCaseSearch)) {
return true;
} else if (article.getTitle().toLowerCase().contains(lowerCaseSearch)) {
return true;
} else if (article.getYear().toString().toLowerCase().contains(lowerCaseSearch)) {
return true;
} else {
for (Model model : models) {
if (model.getName().toLowerCase().contains(lowerCaseSearch)) {
return true;
}
}
}
switch (sortColumn.toLowerCase().trim()) {
case "":
return null;
case "pubmedid":
return ArticleProperty.PUBMED_ID;
case "year":
return ArticleProperty.YEAR;
case "journal":
return ArticleProperty.JOURNAL;
case "title":
return ArticleProperty.TITLE;
default:
throw new QueryException("Unknown sort order: " + sortColumn);
}
return false;
}
/**
......@@ -259,18 +203,4 @@ public class PublicationsRestImpl extends BaseRestImpl {
}
enum SortColumn {
PUBMED_ID("pubmedId"),
YEAR("year"),
JOURNAL("journal"),
TITLE("title"),
AUTHORS("authors");
private String commonName;
SortColumn(String commonName) {
this.commonName = commonName;
}
}
}
......@@ -90,8 +90,8 @@ public class ModelService implements IModelService {
this.projectDao = projectDao;
this.backend = backend;
this.miriamConnector = miriamConnector;
this.sbmlParameterDao= sbmlParameterDao;
this.sbmlUnitDao=sbmlUnitDao;
this.sbmlParameterDao = sbmlParameterDao;
this.sbmlUnitDao = sbmlUnitDao;
}
@Override
......
package lcsb.mapviewer.services.impl;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lcsb.mapviewer.annotation.services.PubmedParser;
import lcsb.mapviewer.annotation.services.PubmedSearchException;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.model.Article;
import lcsb.mapviewer.persist.dao.ArticleDao;
import lcsb.mapviewer.persist.dao.ArticleProperty;
import lcsb.mapviewer.services.interfaces.IPublicationService;
@Transactional
@Service
public class PublicationService implements IPublicationService {
Logger logger = LogManager.getLogger();
@Autowired
private ArticleDao articleDao;
@Autowired
private PubmedParser pubmedParser;
@Override
public Page<Article> getByFilter(Pageable pageable, Map<ArticleProperty, Object> filterOptions) {
List<String> missingIds = articleDao.getMissingByFilter(filterOptions);
for (String id : missingIds) {
try {
Article article = pubmedParser.getPubmedArticleById(id);
articleDao.add(article);
} catch (PubmedSearchException e) {
logger.error("Problem with accessing article", e);
}
}
return articleDao.getByFilter(pageable, filterOptions);
}
@Override
public long getCountByFilter(Pageable pageable, Map<ArticleProperty, Object> filterOptions) {
return articleDao.getCountByFilter(filterOptions);
}
}
......@@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.Transactional;
import com.google.gson.internal.LinkedTreeMap;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.model.Project;
import lcsb.mapviewer.model.map.MiriamType;
import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
......@@ -16,6 +17,7 @@ import lcsb.mapviewer.model.map.model.ModelData;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.persist.dao.ProjectDao;
import lcsb.mapviewer.persist.dao.map.ReactionDao;
import lcsb.mapviewer.persist.dao.map.ReactionProperty;
import lcsb.mapviewer.services.ObjectNotFoundException;
import lcsb.mapviewer.services.QueryException;
import lcsb.mapviewer.services.interfaces.IModelService;
......@@ -84,7 +86,8 @@ public class ReactionService implements IReactionService {
@Override
public Map<MiriamType, Integer> getAnnotationStatistics(String projectId, String mapId) throws QueryException {
Map<MiriamType, Integer> elementAnnotations = new LinkedTreeMap<>();
Map<MiriamType, Integer> data = reactionDao.getAnnotationStatistics(modelService.getModelsByMapId(projectId, mapId));
Map<MiriamType, Integer> data = reactionDao
.getAnnotationStatistics(modelService.getModelsByMapId(projectId, mapId));
for (MiriamType mt : MiriamType.values()) {
if (data.get(mt) != null) {
elementAnnotations.put(mt, data.get(mt));
......@@ -95,4 +98,9 @@ public class ReactionService implements IReactionService {
return elementAnnotations;
}
@Override
public List<Reaction> getReactionsByFilter(Map<ReactionProperty, List<? extends Object>> reactionSearch) {
return reactionDao.getByFilter(reactionSearch);
}
}
package lcsb.mapviewer.services.interfaces;
import java.util.Map;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import lcsb.mapviewer.model.Article;
import lcsb.mapviewer.persist.dao.ArticleProperty;
public interface IPublicationService {
Page<Article> getByFilter(Pageable pageable, Map<ArticleProperty, Object> filterOptions);
long getCountByFilter(Pageable pageable, Map<ArticleProperty, Object> filterOptions);
}
......@@ -5,6 +5,7 @@ import java.util.*;
import lcsb.mapviewer.model.map.MiriamType;
import lcsb.mapviewer.model.map.kinetics.SbmlParameter;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.persist.dao.map.ReactionProperty;
import lcsb.mapviewer.services.QueryException;
public interface IReactionService {
......@@ -22,4 +23,6 @@ public interface IReactionService {
Map<MiriamType, Integer> getAnnotationStatistics(String projectId, String mapId) throws QueryException;
List<Reaction> getReactionsByFilter(Map<ReactionProperty, List<? extends Object>> reactionSearch);
}
......@@ -79,8 +79,8 @@ public class PublicationsControllerIntegrationTest extends ControllerIntegration
fieldWithPath("length")
.description("number of entries in this response")
.type("number"),
fieldWithPath("start")
.description("number of first entry in this response")
fieldWithPath("page")
.description("page number of result list")
.type("number"),
fieldWithPath("totalSize")
.description("number of all log entries")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment