diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java index d41fe7960806ce241dbc6fc0bc2ccca5d7b973f7..1fb4da6e601ab07a3c7ac41eb132c059cddaf4ff 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java @@ -1,317 +1,333 @@ -package lcsb.mapviewer.annotation.services; - -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; - -import lcsb.mapviewer.annotation.cache.CachableInterface; -import lcsb.mapviewer.annotation.cache.GeneralCacheInterface; -import lcsb.mapviewer.annotation.cache.SourceNotAvailable; -import lcsb.mapviewer.annotation.cache.XmlSerializer; -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; - -/** - * This class is a backend to publically available pubmed API in - * <a href="http://europepmc.org/RestfulWebService">Europe PubMed Central </a>. - * - * @author Piotr Gawron - * - */ -public class PubmedParser extends CachableInterface implements IExternalService { - - /** - * Pubmed identifier used to check the status of service (functionality from - * {@link IExternalService}). - */ - private static final int SERVICE_STATUS_PUBMED_ID = 12345; - - /** - * Prefix used for caching elements with pubmed identifier as a key. - */ - private static final String PUBMED_PREFIX = "pubmed: "; - - /** - * Length of {@link #PUBMED_PREFIX} string. - */ - private static final int PUBMED_PREFIX_LENGTH = PUBMED_PREFIX.length(); - - /** - * Connector used for accessing data from miriam registry. - */ - @Autowired - private MiriamConnector miriamConnector; - - /** - * Default class logger. - */ - private Logger logger = Logger.getLogger(PubmedParser.class); - - /** - * Object that allows to serialize {@link Article} elements into xml string - * and deserialize xml into {@link Article} objects. - */ - private XmlSerializer<Article> articleSerializer; - - @Override - public String refreshCacheQuery(Object query) throws SourceNotAvailable { - String name; - String result = null; - if (query instanceof String) { - name = (String) query; - if (name.startsWith(PUBMED_PREFIX)) { - Integer id = Integer.valueOf(name.substring(PUBMED_PREFIX_LENGTH)); - result = articleSerializer.objectToString(getPubmedArticleById(id)); - } else { - throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\""); - } - } else { - throw new InvalidArgumentException("Don't know what to do with class: " + query.getClass()); - } - - return result; - } - - /** - * Default constructor. Initializes structures used for transforming - * {@link Article} from/to xml. - */ - public PubmedParser() { - super(PubmedParser.class); - articleSerializer = new XmlSerializer<>(Article.class); - } - - /** - * Returns article data for given pubmed identifier. - * - * @param id - * pubmed identifier - * @return article data - */ - public Article getPubmedArticleById(Integer id) { - String queryString = "pubmed: " + id; - Article result = articleSerializer.xmlToObject(getCacheNode(queryString)); - if (result != null && result.getTitle() != null) { - return result; - } else { - logger.debug("Pubmed article (id=" + id + ") not found in cache. Accessing WebService..."); - } - - result = new Article(); - InputStream mainStream = null; - // InputStream citationStream = null; - try { - String url = "http://www.ebi.ac.uk/europepmc/webservices/rest/search/resulttype=core&query=" - + java.net.URLEncoder.encode("src:med ext_id:" + id, "UTF-8"); - - mainStream = new URL(url).openStream(); - // citationStream = new - // URL("http://www.ebi.ac.uk/europepmc/webservices/rest/MED/" + id + - // "/citations/1/xml") - // .openStream(); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document mainDoc = dBuilder.parse(mainStream); - // Document citationDoc = dBuilder.parse(citationStream); - mainDoc.getDocumentElement().normalize(); - // citationDoc.getDocumentElement().normalize(); - XPathFactory xPathFactory = XPathFactory.newInstance(); - XPath xpath = xPathFactory.newXPath(); - NodeList nodeList = null; - // Hit Count - nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/citedByCount").evaluate(mainDoc, XPathConstants.NODESET); - if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { - try { - result.setCitationCount(Integer.valueOf(nodeList.item(0).getFirstChild().getNodeValue())); - } catch (Exception e) { - } - } - // Title - nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/title").evaluate(mainDoc, XPathConstants.NODESET); - if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { - result.setTitle(nodeList.item(0).getFirstChild().getNodeValue()); - } - // Year - nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/journalInfo/yearOfPublication").evaluate(mainDoc, XPathConstants.NODESET); - if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { - try { - result.setYear(Integer.valueOf(nodeList.item(0).getFirstChild().getNodeValue())); - } catch (Exception e) { - } - } - // Journal - nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/journalInfo/journal/title").evaluate(mainDoc, XPathConstants.NODESET); - if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { - result.setJournal(nodeList.item(0).getFirstChild().getNodeValue()); - } - // Authors - nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/authorString").evaluate(mainDoc, XPathConstants.NODESET); - if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { - List<String> authors = new ArrayList<String>(); - String value = nodeList.item(0).getFirstChild().getNodeValue(); - if (value != null && !value.isEmpty()) { - authors = Arrays.asList(value.split(",")); - } - result.setAuthors(authors); - } - result.setLink(miriamConnector.getUrlString(new MiriamData(MiriamType.PUBMED, id + ""))); - result.setId(id + ""); - - if (result.getTitle() != null && !result.getTitle().trim().isEmpty()) { - setCacheValue(queryString, articleSerializer.objectToString(result)); - } else { - result = null; - } - - } catch (Exception e) { - logger.error(e.getMessage(), e); - } finally { - try { - if (mainStream != null) { - mainStream.close(); - } - /* - * if (citationStream != null) { citationStream.close(); } - */ - } catch (Exception ex) { - } - } - return result; - } - - /** - * This method return html \< a\ > tag with link for pubmed id (with some - * additional information). - * - * @param id - * pubmed identifier - * @param withTextPrefix - * should prefix be added to the tag - * @return link to webpage with pubmed article - */ - public String getHtmlFullLinkForId(Integer id, boolean withTextPrefix) { - String result = ""; - Article article = getPubmedArticleById(id); - result += "<div style=\"float:left;\" title=\"" + article.getTitle() + ", "; - result += article.getStringAuthors() + ", "; - result += article.getYear() + ", "; - result += article.getJournal() + "\">"; - if (withTextPrefix) { - result += "pubmed: "; - } - result += "<a target=\"_blank\" href = \"" + article.getLink() + "\">" + id + "</a> </div>"; - return result; - } - - /** - * This method return html \< a\ > tag with link for pubmed id (with some - * additional information). - * - * @param id - * pubmed identifier - * @return link to webpage with pubmed article - */ - public String getHtmlFullLinkForId(Integer id) { - return getHtmlFullLinkForId(id, true); - } - - /** - * Get the summary of the article. - * - * @param id - * pubmed identifier - * @return summary of the article. - */ - public String getSummary(Integer id) { - Article article = getPubmedArticleById(id); - if (article == null) { - return null; - } - String result = article.getTitle() + ", " + article.getStringAuthors() + ", " + article.getYear() + ", " + article.getJournal(); - return result; - } - - @Override - public ExternalServiceStatus getServiceStatus() { - ExternalServiceStatus status = new ExternalServiceStatus("Europe PubMed Central", "http://europepmc.org/RestfulWebService"); - GeneralCacheInterface cacheCopy = getCache(); - this.setCache(null); - - try { - Article art = getPubmedArticleById(SERVICE_STATUS_PUBMED_ID); - status.setStatus(ExternalServiceStatusType.OK); - if (art == null) { - status.setStatus(ExternalServiceStatusType.DOWN); - } else if (art.getTitle() == null) { - status.setStatus(ExternalServiceStatusType.CHANGED); - } else if (art.getTitle().equals("")) { - status.setStatus(ExternalServiceStatusType.CHANGED); - } - } catch (Exception e) { - logger.error(status.getName() + " is down", e); - status.setStatus(ExternalServiceStatusType.DOWN); - } - this.setCache(cacheCopy); - return status; - } - - /** - * Get the summary of the article. - * - * @param id - * pubmed identifier - * @return summary of the article. - */ - public String getSummary(String id) { - return getSummary(Integer.valueOf(id)); - } - - /** - * @return the miriamConnector - * @see #miriamConnector - */ - public MiriamConnector getMiriamConnector() { - return miriamConnector; - } - - /** - * @param miriamConnector - * the miriamConnector to set - * @see #miriamConnector - */ - public void setMiriamConnector(MiriamConnector miriamConnector) { - this.miriamConnector = miriamConnector; - } - - /** - * @return the articleSerializer - * @see #articleSerializer - */ - protected XmlSerializer<Article> getArticleSerializer() { - return articleSerializer; - } - - /** - * @param articleSerializer - * the articleSerializer to set - * @see #articleSerializer - */ - protected void setArticleSerializer(XmlSerializer<Article> articleSerializer) { - this.articleSerializer = articleSerializer; - } -} +package lcsb.mapviewer.annotation.services; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +import lcsb.mapviewer.annotation.cache.CachableInterface; +import lcsb.mapviewer.annotation.cache.GeneralCacheInterface; +import lcsb.mapviewer.annotation.cache.SourceNotAvailable; +import lcsb.mapviewer.annotation.cache.XmlSerializer; +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; + +/** + * This class is a backend to publically available pubmed API in + * <a href="http://europepmc.org/RestfulWebService">Europe PubMed Central </a>. + * + * @author Piotr Gawron + * + */ +public class PubmedParser extends CachableInterface implements IExternalService { + + /** + * Pubmed identifier used to check the status of service (functionality from + * {@link IExternalService}). + */ + private static final int SERVICE_STATUS_PUBMED_ID = 12345; + + /** + * Prefix used for caching elements with pubmed identifier as a key. + */ + private static final String PUBMED_PREFIX = "pubmed: "; + + /** + * Length of {@link #PUBMED_PREFIX} string. + */ + private static final int PUBMED_PREFIX_LENGTH = PUBMED_PREFIX.length(); + + /** + * Connector used for accessing data from miriam registry. + */ + @Autowired + private MiriamConnector miriamConnector; + + /** + * Default class logger. + */ + private Logger logger = Logger.getLogger(PubmedParser.class); + + /** + * Object that allows to serialize {@link Article} elements into xml string + * and deserialize xml into {@link Article} objects. + */ + private XmlSerializer<Article> articleSerializer; + + @Override + public String refreshCacheQuery(Object query) throws SourceNotAvailable { + String result = null; + try { + if (query instanceof String) { + String name = (String) query; + if (name.startsWith(PUBMED_PREFIX)) { + Integer id = Integer.valueOf(name.substring(PUBMED_PREFIX_LENGTH)); + result = articleSerializer.objectToString(getPubmedArticleById(id)); + } else { + throw new InvalidArgumentException("Don't know what to do with string \"" + query + "\""); + } + } else { + throw new InvalidArgumentException("Don't know what to do with class: " + query.getClass()); + } + } catch (PubmedSearchException e) { + throw new SourceNotAvailable(e); + } + + return result; + } + + /** + * Default constructor. Initializes structures used for transforming + * {@link Article} from/to xml. + */ + public PubmedParser() { + super(PubmedParser.class); + articleSerializer = new XmlSerializer<>(Article.class); + } + + /** + * Returns article data for given pubmed identifier. + * + * @param id + * pubmed identifier + * @return article data + * @throws PubmedSearchException + * thrown when there is a problem with accessing information about + * pubmed + */ + public Article getPubmedArticleById(Integer id) throws PubmedSearchException { + String queryString = "pubmed: " + id; + Article result = articleSerializer.xmlToObject(getCacheNode(queryString)); + if (result != null && result.getTitle() != null) { + return result; + } else { + logger.debug("Pubmed article (id=" + id + ") not found in cache. Accessing WebService..."); + } + + result = new Article(); + InputStream mainStream = null; + // InputStream citationStream = null; + try { + String url = "http://www.ebi.ac.uk/europepmc/webservices/rest/search/resulttype=core&query=" + + java.net.URLEncoder.encode("src:med ext_id:" + id, "UTF-8"); + + mainStream = new URL(url).openStream(); + // citationStream = new + // URL("http://www.ebi.ac.uk/europepmc/webservices/rest/MED/" + id + + // "/citations/1/xml") + // .openStream(); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document mainDoc = dBuilder.parse(mainStream); + // Document citationDoc = dBuilder.parse(citationStream); + mainDoc.getDocumentElement().normalize(); + // citationDoc.getDocumentElement().normalize(); + XPathFactory xPathFactory = XPathFactory.newInstance(); + XPath xpath = xPathFactory.newXPath(); + NodeList nodeList = null; + // Hit Count + nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/citedByCount").evaluate(mainDoc, XPathConstants.NODESET); + if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { + try { + result.setCitationCount(Integer.valueOf(nodeList.item(0).getFirstChild().getNodeValue())); + } catch (Exception e) { + } + } + // Title + nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/title").evaluate(mainDoc, XPathConstants.NODESET); + if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { + result.setTitle(nodeList.item(0).getFirstChild().getNodeValue()); + } + // Year + nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/journalInfo/yearOfPublication").evaluate(mainDoc, XPathConstants.NODESET); + if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { + try { + result.setYear(Integer.valueOf(nodeList.item(0).getFirstChild().getNodeValue())); + } catch (Exception e) { + } + } + // Journal + nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/journalInfo/journal/title").evaluate(mainDoc, XPathConstants.NODESET); + if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { + result.setJournal(nodeList.item(0).getFirstChild().getNodeValue()); + } + // Authors + nodeList = (NodeList) xpath.compile("/responseWrapper/resultList/result/authorString").evaluate(mainDoc, XPathConstants.NODESET); + if (nodeList != null && nodeList.getLength() > 0 && nodeList.item(0).getFirstChild() != null) { + List<String> authors = new ArrayList<String>(); + String value = nodeList.item(0).getFirstChild().getNodeValue(); + if (value != null && !value.isEmpty()) { + authors = Arrays.asList(value.split(",")); + } + result.setAuthors(authors); + } + result.setLink(miriamConnector.getUrlString(new MiriamData(MiriamType.PUBMED, id + ""))); + result.setId(id + ""); + + if (result.getTitle() != null && !result.getTitle().trim().isEmpty()) { + setCacheValue(queryString, articleSerializer.objectToString(result)); + } else { + result = null; + } + + } catch (Exception e) { + throw new PubmedSearchException(e); + } finally { + try { + if (mainStream != null) { + mainStream.close(); + } + } catch (Exception ex) { + logger.error("Problem with closing stream", ex); + } + } + return result; + } + + /** + * This method return html \< a\ > tag with link for pubmed id (with some + * additional information). + * + * @param id + * pubmed identifier + * @param withTextPrefix + * should prefix be added to the tag + * @return link to webpage with pubmed article + * @throws PubmedSearchException + * thrown when there is a problem with accessing information about + * pubmed + */ + public String getHtmlFullLinkForId(Integer id, boolean withTextPrefix) throws PubmedSearchException { + String result = ""; + Article article = getPubmedArticleById(id); + result += "<div style=\"float:left;\" title=\"" + article.getTitle() + ", "; + result += article.getStringAuthors() + ", "; + result += article.getYear() + ", "; + result += article.getJournal() + "\">"; + if (withTextPrefix) { + result += "pubmed: "; + } + result += "<a target=\"_blank\" href = \"" + article.getLink() + "\">" + id + "</a> </div>"; + return result; + } + + /** + * This method return html \< a\ > tag with link for pubmed id (with some + * additional information). + * + * @param id + * pubmed identifier + * @return link to webpage with pubmed article + * @throws PubmedSearchException + * thrown when there is a problem with accessing information about + * pubmed + */ + public String getHtmlFullLinkForId(Integer id) throws PubmedSearchException { + return getHtmlFullLinkForId(id, true); + } + + /** + * Get the summary of the article. + * + * @param id + * pubmed identifier + * @return summary of the article. + * @throws PubmedSearchException + * thrown when there is a problem with accessing information about + * pubmed + */ + public String getSummary(Integer id) throws PubmedSearchException { + Article article = getPubmedArticleById(id); + if (article == null) { + return null; + } + String result = article.getTitle() + ", " + article.getStringAuthors() + ", " + article.getYear() + ", " + article.getJournal(); + return result; + } + + @Override + public ExternalServiceStatus getServiceStatus() { + ExternalServiceStatus status = new ExternalServiceStatus("Europe PubMed Central", "http://europepmc.org/RestfulWebService"); + GeneralCacheInterface cacheCopy = getCache(); + this.setCache(null); + + try { + Article art = getPubmedArticleById(SERVICE_STATUS_PUBMED_ID); + status.setStatus(ExternalServiceStatusType.OK); + if (art == null) { + status.setStatus(ExternalServiceStatusType.DOWN); + } else if (art.getTitle() == null) { + status.setStatus(ExternalServiceStatusType.CHANGED); + } else if (art.getTitle().equals("")) { + status.setStatus(ExternalServiceStatusType.CHANGED); + } + } catch (Exception e) { + logger.error(status.getName() + " is down", e); + status.setStatus(ExternalServiceStatusType.DOWN); + } + this.setCache(cacheCopy); + return status; + } + + /** + * Get the summary of the article. + * + * @param id + * pubmed identifier + * @return summary of the article. + * @throws PubmedSearchException + * thrown when there is a problem with accessing information about + * pubmed + */ + public String getSummary(String id) throws PubmedSearchException { + return getSummary(Integer.valueOf(id)); + } + + /** + * @return the miriamConnector + * @see #miriamConnector + */ + public MiriamConnector getMiriamConnector() { + return miriamConnector; + } + + /** + * @param miriamConnector + * the miriamConnector to set + * @see #miriamConnector + */ + public void setMiriamConnector(MiriamConnector miriamConnector) { + this.miriamConnector = miriamConnector; + } + + /** + * @return the articleSerializer + * @see #articleSerializer + */ + protected XmlSerializer<Article> getArticleSerializer() { + return articleSerializer; + } + + /** + * @param articleSerializer + * the articleSerializer to set + * @see #articleSerializer + */ + protected void setArticleSerializer(XmlSerializer<Article> articleSerializer) { + this.articleSerializer = articleSerializer; + } +} diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedSearchException.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedSearchException.java new file mode 100644 index 0000000000000000000000000000000000000000..65e29dd0c3b9cbac236ba51805a84434111cfb00 --- /dev/null +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedSearchException.java @@ -0,0 +1,48 @@ +package lcsb.mapviewer.annotation.services; + +/** + * Exception thrown when there was a problem when searching for a pubmed data. + * + * @author Piotr Gawron + * + */ +public class PubmedSearchException extends Exception { + + /** + * Default constructor. + * + * @param string + * exception message + */ + public PubmedSearchException(String string) { + super(string); + } + + /** + * Default constructor. + * + * @param e + * parent exception + */ + public PubmedSearchException(Exception e) { + super(e); + } + + /** + * Default constructor. + * + * @param message + * exception message + * @param e + * source exception + */ + public PubmedSearchException(String message, Exception e) { + super(message, e); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/PubmedParserTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/PubmedParserTest.java index 31204c76a806ba03e549dcae47c7bd1d4f766167..1dd83f20b8c485ca10c8d6dc347190ef97ac328d 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/PubmedParserTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/PubmedParserTest.java @@ -1,236 +1,236 @@ -package lcsb.mapviewer.annotation.services; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.log4j.Logger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import lcsb.mapviewer.annotation.AnnotationTestFunctions; -import lcsb.mapviewer.annotation.cache.GeneralCacheInterface; -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.common.Configuration; -import lcsb.mapviewer.common.exception.InvalidArgumentException; - -public class PubmedParserTest extends AnnotationTestFunctions { - Logger logger = Logger.getLogger(PubmedParserTest.class); - private boolean status; - private boolean status2; - @Autowired - PubmedParser pubmedParser; - - @Autowired - private GeneralCacheInterface cache; - - @Before - public void setUp() throws Exception { - status = Configuration.isDbCacheOn(); - status2 = Configuration.isApplicationCacheOn(); - } - - @After - public void tearDown() throws Exception { - Configuration.setDbCacheOn(status); - Configuration.setApplicationCacheOn(status2); - } - - @Test - public void test() { - try { - Configuration.setDbCacheOn(false); - Configuration.setApplicationCacheOn(false); - Article art = pubmedParser.getPubmedArticleById(9481670); - assertNotNull(art); - assertEquals( - "Adjacent asparagines in the NR2-subunit of the NMDA receptor channel control the voltage-dependent block by extracellular Mg2+.", art.getTitle()); - assertEquals((Integer) 1998, art.getYear()); - assertEquals("The Journal of physiology", art.getJournal()); - assertTrue(art.getStringAuthors().contains("Wollmuth")); - assertTrue(art.getStringAuthors().contains("Kuner")); - assertTrue(art.getStringAuthors().contains("Sakmann")); - - } catch (Exception e) { - e.printStackTrace(); - fail("Unknown exception " + e.getMessage()); - } - } - - @Test - public void testCache() { - try { - Configuration.setDbCacheOn(true); - Configuration.setApplicationCacheOn(true); - - Article art = pubmedParser.getPubmedArticleById(9481671); - assertNotNull(art); - - } catch (Exception e) { - e.printStackTrace(); - fail("Unknown exception " + e.getMessage()); - } - } - - @Test - public void testSerialization() { - try { - - Article art = new Article(); - List<String> list = new ArrayList<String>(); - list.add("aaa"); - list.add("bbb"); - art.setTitle("ttt"); - art.setAuthors(list); - art.setJournal("jjjj"); - art.setYear(123); - - String serialString = pubmedParser.getArticleSerializer().objectToString(art); - - assertTrue(serialString.contains("aaa")); - assertTrue(serialString.contains("bbb")); - assertTrue(serialString.contains("ttt")); - assertTrue(serialString.contains("jjjj")); - assertTrue(serialString.contains("123")); - - Article art2 = pubmedParser.getArticleSerializer().xmlToObject(getNodeFromXmlString(serialString)); - - assertEquals(art.getStringAuthors(), art2.getStringAuthors()); - assertEquals(art.getTitle(), art2.getTitle()); - assertEquals(art.getJournal(), art2.getJournal()); - assertEquals(art.getYear(), art2.getYear()); - - } catch (Exception e) { - e.printStackTrace(); - fail("Exception occurred"); - } - } - - /** - * This case was problematic with old API used to retrieve data from pubmed - */ - @Test - public void testProblematicCase() { - try { - - Article art = pubmedParser.getPubmedArticleById(22363258); - assertNotNull(art); - - } catch (Exception e) { - e.printStackTrace(); - fail("Unknown exception " + e.getMessage()); - } - } - - @Test - public void testCitationCount() { - try { - - Article art = pubmedParser.getPubmedArticleById(18400456); - assertNotNull(art); - assertTrue(art.getCitationCount() >= 53); - - } catch (Exception e) { - e.printStackTrace(); - fail("Unknown exception " + e.getMessage()); - } - } - - @Test - public void testGetSummary() { - try { - - String summary = pubmedParser.getSummary(18400456); - assertNotNull(summary); - assertFalse(summary.isEmpty()); - - } catch (Exception e) { - e.printStackTrace(); - fail("Unknown exception " + e.getMessage()); - } - } - - @Test - public void testGetSummary2() { - try { - - String summary = pubmedParser.getSummary(23644949); - assertNull(summary); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - // wait max 15 second - public void testCachableInterface() throws Exception { - String query = "pubmed: 2112"; - try { - String newRes = "hello"; - waitForRefreshCacheQueueToEmpty(); - - cache.setCachedQuery(query, pubmedParser.getCacheType(), newRes); - cache.invalidateByQuery(query, pubmedParser.getCacheType()); - - waitForRefreshCacheQueueToEmpty(); - - String res = cache.getStringByQuery(query, pubmedParser.getCacheType()); - - assertNotNull(res); - - assertFalse("Value wasn't refreshed from db", newRes.equals(res)); - - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testRefreshInvalidCacheQuery() throws Exception { - try { - pubmedParser.refreshCacheQuery("invalid_query"); - fail("Exception expected"); - } catch (InvalidArgumentException e) { - assertTrue(e.getMessage().contains("Don't know what to do")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testRefreshInvalidCacheQuery2() throws Exception { - try { - pubmedParser.refreshCacheQuery(new Object()); - fail("Exception expected"); - } catch (InvalidArgumentException e) { - assertTrue(e.getMessage().contains("Don't know what to do")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetHtmlFullLinkForId() throws Exception { - try { - String htmlString = pubmedParser.getHtmlFullLinkForId(1234); - assertTrue(htmlString.contains("Change in the kinetics of sulphacetamide tissue distribution")); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - -} +package lcsb.mapviewer.annotation.services; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.AnnotationTestFunctions; +import lcsb.mapviewer.annotation.cache.GeneralCacheInterface; +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.common.exception.InvalidArgumentException; + +public class PubmedParserTest extends AnnotationTestFunctions { + Logger logger = Logger.getLogger(PubmedParserTest.class); + private boolean status; + private boolean status2; + @Autowired + PubmedParser pubmedParser; + + @Autowired + private GeneralCacheInterface cache; + + @Before + public void setUp() throws Exception { + status = Configuration.isDbCacheOn(); + status2 = Configuration.isApplicationCacheOn(); + } + + @After + public void tearDown() throws Exception { + Configuration.setDbCacheOn(status); + Configuration.setApplicationCacheOn(status2); + } + + @Test + public void test() { + try { + Configuration.setDbCacheOn(false); + Configuration.setApplicationCacheOn(false); + Article art = pubmedParser.getPubmedArticleById(9481670); + assertNotNull(art); + assertEquals( + "Adjacent asparagines in the NR2-subunit of the NMDA receptor channel control the voltage-dependent block by extracellular Mg2+.", art.getTitle()); + assertEquals((Integer) 1998, art.getYear()); + assertEquals("The Journal of physiology", art.getJournal()); + assertTrue(art.getStringAuthors().contains("Wollmuth")); + assertTrue(art.getStringAuthors().contains("Kuner")); + assertTrue(art.getStringAuthors().contains("Sakmann")); + + } catch (Exception e) { + e.printStackTrace(); + fail("Unknown exception " + e.getMessage()); + } + } + + @Test + public void testCache() { + try { + Configuration.setDbCacheOn(true); + Configuration.setApplicationCacheOn(true); + + Article art = pubmedParser.getPubmedArticleById(9481671); + assertNotNull(art); + + } catch (Exception e) { + e.printStackTrace(); + fail("Unknown exception " + e.getMessage()); + } + } + + @Test + public void testSerialization() { + try { + + Article art = new Article(); + List<String> list = new ArrayList<String>(); + list.add("aaa"); + list.add("bbb"); + art.setTitle("ttt"); + art.setAuthors(list); + art.setJournal("jjjj"); + art.setYear(123); + + String serialString = pubmedParser.getArticleSerializer().objectToString(art); + + assertTrue(serialString.contains("aaa")); + assertTrue(serialString.contains("bbb")); + assertTrue(serialString.contains("ttt")); + assertTrue(serialString.contains("jjjj")); + assertTrue(serialString.contains("123")); + + Article art2 = pubmedParser.getArticleSerializer().xmlToObject(getNodeFromXmlString(serialString)); + + assertEquals(art.getStringAuthors(), art2.getStringAuthors()); + assertEquals(art.getTitle(), art2.getTitle()); + assertEquals(art.getJournal(), art2.getJournal()); + assertEquals(art.getYear(), art2.getYear()); + + } catch (Exception e) { + e.printStackTrace(); + fail("Exception occurred"); + } + } + + /** + * This case was problematic with old API used to retrieve data from pubmed + */ + @Test + public void testProblematicCase() { + try { + + Article art = pubmedParser.getPubmedArticleById(22363258); + assertNotNull(art); + + } catch (Exception e) { + e.printStackTrace(); + fail("Unknown exception " + e.getMessage()); + } + } + + @Test + public void testCitationCount() { + try { + + Article art = pubmedParser.getPubmedArticleById(18400456); + assertNotNull(art); + assertTrue(art.getCitationCount() >= 53); + + } catch (Exception e) { + e.printStackTrace(); + fail("Unknown exception " + e.getMessage()); + } + } + + @Test + public void testGetSummary() { + try { + + String summary = pubmedParser.getSummary(18400456); + assertNotNull(summary); + assertFalse(summary.isEmpty()); + + } catch (Exception e) { + e.printStackTrace(); + fail("Unknown exception " + e.getMessage()); + } + } + + @Test + public void testGetSummary2() throws Exception { + try { + + String summary = pubmedParser.getSummary(23644949); + assertNull(summary); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + // wait max 15 second + public void testCachableInterface() throws Exception { + String query = "pubmed: 2112"; + try { + String newRes = "hello"; + waitForRefreshCacheQueueToEmpty(); + + cache.setCachedQuery(query, pubmedParser.getCacheType(), newRes); + cache.invalidateByQuery(query, pubmedParser.getCacheType()); + + waitForRefreshCacheQueueToEmpty(); + + String res = cache.getStringByQuery(query, pubmedParser.getCacheType()); + + assertNotNull(res); + + assertFalse("Value wasn't refreshed from db", newRes.equals(res)); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testRefreshInvalidCacheQuery() throws Exception { + try { + pubmedParser.refreshCacheQuery("invalid_query"); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + assertTrue(e.getMessage().contains("Don't know what to do")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testRefreshInvalidCacheQuery2() throws Exception { + try { + pubmedParser.refreshCacheQuery(new Object()); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + assertTrue(e.getMessage().contains("Don't know what to do")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testGetHtmlFullLinkForId() throws Exception { + try { + String htmlString = pubmedParser.getHtmlFullLinkForId(1234); + assertTrue(htmlString.contains("Change in the kinetics of sulphacetamide tissue distribution")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + +} diff --git a/console/src/main/java/lcsb/mapviewer/run/ReactomePrediction.java b/console/src/main/java/lcsb/mapviewer/run/ReactomePrediction.java index a3134a302ebcaa1d79893e66d6fae71cc4b5dead..22b837ca221828732808816daf90d61818d49783 100644 --- a/console/src/main/java/lcsb/mapviewer/run/ReactomePrediction.java +++ b/console/src/main/java/lcsb/mapviewer/run/ReactomePrediction.java @@ -1,337 +1,339 @@ -package lcsb.mapviewer.run; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.common.IProgressUpdater; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.converter.ConverterParams; -import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.persist.ApplicationContextLoader; -import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject; -import lcsb.mapviewer.reactome.model.ReactomeLiteratureReference; -import lcsb.mapviewer.reactome.model.ReactomePublication; -import lcsb.mapviewer.reactome.model.ReactomeReactionlikeEvent; -import lcsb.mapviewer.reactome.model.ReactomeURL; -import lcsb.mapviewer.reactome.utils.DataSourceUpdater; -import lcsb.mapviewer.reactome.utils.PredictionResult; -import lcsb.mapviewer.reactome.utils.PredictionResult.PredictionStatus; -import lcsb.mapviewer.reactome.utils.ReactionComparator; -import lcsb.mapviewer.reactome.utils.ReactomeQueryUtil; - -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * This class create a raport about data that might be added to PD-map based on - * reactome data and some text mining information. - * - * @author Piotr Gawron - * - */ -public class ReactomePrediction { - /** - * How many nodes in the reaction must match on both sides (reactome and ours) - * to consider reaction similar. - */ - private static final int PREDICTION_THRESHOLD = 3; - - /** - * Number of nanoseconds in the second. - */ - private static final double NANOSECONDS_IN_SECOND = 1000000000.0; - - /** - * Model used for generating raport. - */ - private Model model; - - /** - * Local backend to the pubmed data. - */ - @Autowired - private PubmedParser pubmedParser; - - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(ReactomePrediction.class); - - /** - * Comparator of reactions between our model and reactome. - */ - @Autowired - private ReactionComparator reactionComparator; - - /** - * Class used for accessing reactome data. - */ - @Autowired - private DataSourceUpdater rc; - - /** - * Util class used for manipulating information in reactome objects. - */ - @Autowired - private ReactomeQueryUtil rcu; - - /** - * Static main method used to run this stand alone code. - * - * @param args - * command line arguments - */ - public static void main(String[] args) { - long startTime = System.nanoTime(); - PropertyConfigurator.configure("src/main/webapp/WEB-INF/resources/log4j.properties"); - ReactomePrediction main = new ReactomePrediction(); - ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); - ApplicationContextLoader.injectDependencies(main); - main.run(); - long endTime = System.nanoTime(); - - long duration = endTime - startTime; - double sec = duration / NANOSECONDS_IN_SECOND; - System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); - } - - /** - * Generates prediction report. - */ - public void run() { - try { - model = new CellDesignerXmlParser().createModel(new ConverterParams().filename(PdMapAnnotations.getLastPdFilename())); - - Set<ReactomeReactionlikeEvent> reactions = new HashSet<ReactomeReactionlikeEvent>(); - // problematic reaction with complex of complex of molecule - for (Reaction reaction : model.getReactions()) { - for (String stableIdentifier : rcu.getReactomeIdentifiersForReaction(reaction)) { - ReactomeDatabaseObject obj = rc.getFullObjectForStableIdentifier(stableIdentifier); - if (obj != null) { - if (obj instanceof ReactomeReactionlikeEvent) { - reactions.add((ReactomeReactionlikeEvent) obj); - } - } - } - } - List<String> pubmedIds = loadPubmedIds("testFiles/data_mining/pd_pmids.txt"); - List<PredictionResult> newReaction = new ArrayList<PredictionResult>(); - logger.debug("Structure analysis"); - newReaction.addAll(rcu.getExtendedReactionsForKnownReactions(reactions, PREDICTION_THRESHOLD)); - logger.debug("Data mining analysis"); - newReaction.addAll(rcu.getExtendedReactionsForPubmedPublicationsWithTabuReaction(pubmedIds, reactions)); - Collections.sort(newReaction, PredictionResult.SCORE_COMPARATOR); - - printHeader(); - for (PredictionResult prediction : newReaction) { - printResult(prediction); - } - printFooter(newReaction); - - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - } - - /** - * Load pubmed identifiers from a file. - * - * @param fileName - * file with pubmed ids - * @return list of pubmed ids - * @throws IOException - * thrown when there are problems with a file - */ - private List<String> loadPubmedIds(String fileName) throws IOException { - List<String> result = new ArrayList<String>(); - BufferedReader br = new BufferedReader(new FileReader(fileName)); - try { - String line; - while ((line = br.readLine()) != null) { - result.add(line); - } - } finally { - br.close(); - } - return result; - } - - /** - * Prints report footer. - * - * @param results - * results used for generating report - */ - private void printFooter(Collection<PredictionResult> results) { - writer.println("</table>"); - - writer.println("Suggested reactions: " + results.size()); - - writer.println("</body></html>"); - writer.close(); - - } - - /** - * Object used for writing the report. - */ - private PrintWriter writer; - - /** - * Creates stream for report output and prints report header. - * - * @throws FileNotFoundException - * thrown when file with the report cannot be found - * @throws UnsupportedEncodingException - * when there are problesm with encoding - */ - private void printHeader() throws FileNotFoundException, UnsupportedEncodingException { - writer = new PrintWriter("out/report/report-prediction.html", "UTF-8"); - writer.println("<html><head></head><body>"); - writer.println("<table cellspacing=\"0\">"); - - String resultString = "<tr>"; - resultString += "<td" + style + ">Reaction</td>"; - resultString += "<td" + style + ">REACTOME ID</td>"; - resultString += "<td" + style + ">Status</td>"; - resultString += "<td" + style + ">Score</td>"; - resultString += "<td" + style + ">References:</td>"; - resultString += "</tr>"; - writer.println(resultString); - - } - - /** - * Formater used for decimals. - */ - - private DecimalFormat df = new DecimalFormat("#.##"); - - /** - * Style used for result cell. - */ - private String style = " style=\"border-width:1;border-style:solid;border-color:#000000;\" "; - - /** - * Prints one prediction row of the result. - * - * @param result - * prediction result - */ - private void printResult(PredictionResult result) { - String color = "#FFFFFF"; - String status = ""; - if (PredictionStatus.STRUCTURE.equals(result.getStatus())) { - color = "#A2E037"; - status = "STRUCTURE"; - } else if (PredictionStatus.DATA_MINIG.equals(result.getStatus())) { - color = "#DDDDDD"; - status = "DATA MINING"; - } else { - logger.warn("Unknown type: " + result.getStatus()); - } - String resultString = "<tr bgcolor = \"" + color + "\">"; - resultString += "<td" + style + ">" + result.getReaction().getDisplayName() + "</td>"; - - String reactomId = result.getReaction().getStableIdentifier().getIdentifier() + "." + result.getReaction().getStableIdentifier().getIdentifierVersion(); - resultString += "<td" + style + "><a target=\"_blank\" href=\"" + rcu.getReactomeUrlForStableIdentifier(reactomId) + "\">" + reactomId + "</a></td>"; - - resultString += "<td" + style + ">" + status + "</td>"; - resultString += "<td" + style + ">" + df.format(result.getScore() * IProgressUpdater.MAX_PROGRESS) + "%</td>"; - resultString += "<td" + style + ">"; - for (ReactomePublication reference : result.getReaction().getLiteratureReferences()) { - if (reference instanceof ReactomeLiteratureReference) { - resultString += pubmedParser.getHtmlFullLinkForId(((ReactomeLiteratureReference) reference).getPubMedIdentifier()); - } else if (reference instanceof ReactomeURL) { - resultString += reference.getTitle() + "; " + ((ReactomeURL) reference).getUniformResourceLocator(); - } else { - throw new InvalidArgumentException("Unknown clas type: " + reference.getClass()); - } - } - resultString += "</td>"; - resultString += "</tr>"; - writer.println(resultString); - System.out.println(resultString); - } - - /** - * @return the pubmedParser - */ - public PubmedParser getPubmedParser() { - return pubmedParser; - } - - /** - * @param pubmedParser - * the pubmedParser to set - */ - public void setPubmedParser(PubmedParser pubmedParser) { - this.pubmedParser = pubmedParser; - } - - /** - * @return the reactionComparator - */ - public ReactionComparator getReactionComparator() { - return reactionComparator; - } - - /** - * @param reactionComparator - * the reactionComparator to set - */ - public void setReactionComparator(ReactionComparator reactionComparator) { - this.reactionComparator = reactionComparator; - } - - /** - * @return the rc - * @see #rc - */ - public DataSourceUpdater getRc() { - return rc; - } - - /** - * @param rc - * the rc to set - * @see #rc - */ - public void setRc(DataSourceUpdater rc) { - this.rc = rc; - } - - /** - * @return the rcu - * @see #rcu - */ - public ReactomeQueryUtil getRcu() { - return rcu; - } - - /** - * @param rcu - * the rcu to set - * @see #rcu - */ - public void setRcu(ReactomeQueryUtil rcu) { - this.rcu = rcu; - } - -} +package lcsb.mapviewer.run; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.common.IProgressUpdater; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.converter.ConverterParams; +import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.persist.ApplicationContextLoader; +import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject; +import lcsb.mapviewer.reactome.model.ReactomeLiteratureReference; +import lcsb.mapviewer.reactome.model.ReactomePublication; +import lcsb.mapviewer.reactome.model.ReactomeReactionlikeEvent; +import lcsb.mapviewer.reactome.model.ReactomeURL; +import lcsb.mapviewer.reactome.utils.DataSourceUpdater; +import lcsb.mapviewer.reactome.utils.PredictionResult; +import lcsb.mapviewer.reactome.utils.PredictionResult.PredictionStatus; +import lcsb.mapviewer.reactome.utils.ReactionComparator; +import lcsb.mapviewer.reactome.utils.ReactomeQueryUtil; + +/** + * This class create a raport about data that might be added to PD-map based on + * reactome data and some text mining information. + * + * @author Piotr Gawron + * + */ +public class ReactomePrediction { + /** + * How many nodes in the reaction must match on both sides (reactome and ours) + * to consider reaction similar. + */ + private static final int PREDICTION_THRESHOLD = 3; + + /** + * Number of nanoseconds in the second. + */ + private static final double NANOSECONDS_IN_SECOND = 1000000000.0; + + /** + * Model used for generating raport. + */ + private Model model; + + /** + * Local backend to the pubmed data. + */ + @Autowired + private PubmedParser pubmedParser; + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(ReactomePrediction.class); + + /** + * Comparator of reactions between our model and reactome. + */ + @Autowired + private ReactionComparator reactionComparator; + + /** + * Class used for accessing reactome data. + */ + @Autowired + private DataSourceUpdater rc; + + /** + * Util class used for manipulating information in reactome objects. + */ + @Autowired + private ReactomeQueryUtil rcu; + + /** + * Static main method used to run this stand alone code. + * + * @param args + * command line arguments + */ + public static void main(String[] args) { + long startTime = System.nanoTime(); + PropertyConfigurator.configure("src/main/webapp/WEB-INF/resources/log4j.properties"); + ReactomePrediction main = new ReactomePrediction(); + ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); + ApplicationContextLoader.injectDependencies(main); + main.run(); + long endTime = System.nanoTime(); + + long duration = endTime - startTime; + double sec = duration / NANOSECONDS_IN_SECOND; + System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); + } + + /** + * Generates prediction report. + */ + public void run() { + try { + model = new CellDesignerXmlParser().createModel(new ConverterParams().filename(PdMapAnnotations.getLastPdFilename())); + + Set<ReactomeReactionlikeEvent> reactions = new HashSet<ReactomeReactionlikeEvent>(); + // problematic reaction with complex of complex of molecule + for (Reaction reaction : model.getReactions()) { + for (String stableIdentifier : rcu.getReactomeIdentifiersForReaction(reaction)) { + ReactomeDatabaseObject obj = rc.getFullObjectForStableIdentifier(stableIdentifier); + if (obj != null) { + if (obj instanceof ReactomeReactionlikeEvent) { + reactions.add((ReactomeReactionlikeEvent) obj); + } + } + } + } + List<String> pubmedIds = loadPubmedIds("testFiles/data_mining/pd_pmids.txt"); + List<PredictionResult> newReaction = new ArrayList<PredictionResult>(); + logger.debug("Structure analysis"); + newReaction.addAll(rcu.getExtendedReactionsForKnownReactions(reactions, PREDICTION_THRESHOLD)); + logger.debug("Data mining analysis"); + newReaction.addAll(rcu.getExtendedReactionsForPubmedPublicationsWithTabuReaction(pubmedIds, reactions)); + Collections.sort(newReaction, PredictionResult.SCORE_COMPARATOR); + + printHeader(); + for (PredictionResult prediction : newReaction) { + printResult(prediction); + } + printFooter(newReaction); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + } + + /** + * Load pubmed identifiers from a file. + * + * @param fileName + * file with pubmed ids + * @return list of pubmed ids + * @throws IOException + * thrown when there are problems with a file + */ + private List<String> loadPubmedIds(String fileName) throws IOException { + List<String> result = new ArrayList<String>(); + BufferedReader br = new BufferedReader(new FileReader(fileName)); + try { + String line; + while ((line = br.readLine()) != null) { + result.add(line); + } + } finally { + br.close(); + } + return result; + } + + /** + * Prints report footer. + * + * @param results + * results used for generating report + */ + private void printFooter(Collection<PredictionResult> results) { + writer.println("</table>"); + + writer.println("Suggested reactions: " + results.size()); + + writer.println("</body></html>"); + writer.close(); + + } + + /** + * Object used for writing the report. + */ + private PrintWriter writer; + + /** + * Creates stream for report output and prints report header. + * + * @throws FileNotFoundException + * thrown when file with the report cannot be found + * @throws UnsupportedEncodingException + * when there are problesm with encoding + */ + private void printHeader() throws FileNotFoundException, UnsupportedEncodingException { + writer = new PrintWriter("out/report/report-prediction.html", "UTF-8"); + writer.println("<html><head></head><body>"); + writer.println("<table cellspacing=\"0\">"); + + String resultString = "<tr>"; + resultString += "<td" + style + ">Reaction</td>"; + resultString += "<td" + style + ">REACTOME ID</td>"; + resultString += "<td" + style + ">Status</td>"; + resultString += "<td" + style + ">Score</td>"; + resultString += "<td" + style + ">References:</td>"; + resultString += "</tr>"; + writer.println(resultString); + + } + + /** + * Formater used for decimals. + */ + + private DecimalFormat df = new DecimalFormat("#.##"); + + /** + * Style used for result cell. + */ + private String style = " style=\"border-width:1;border-style:solid;border-color:#000000;\" "; + + /** + * Prints one prediction row of the result. + * + * @param result + * prediction result + * @throws Exception + * thrown when there is a problem with printing + */ + private void printResult(PredictionResult result) throws Exception { + String color = "#FFFFFF"; + String status = ""; + if (PredictionStatus.STRUCTURE.equals(result.getStatus())) { + color = "#A2E037"; + status = "STRUCTURE"; + } else if (PredictionStatus.DATA_MINIG.equals(result.getStatus())) { + color = "#DDDDDD"; + status = "DATA MINING"; + } else { + logger.warn("Unknown type: " + result.getStatus()); + } + String resultString = "<tr bgcolor = \"" + color + "\">"; + resultString += "<td" + style + ">" + result.getReaction().getDisplayName() + "</td>"; + + String reactomId = result.getReaction().getStableIdentifier().getIdentifier() + "." + result.getReaction().getStableIdentifier().getIdentifierVersion(); + resultString += "<td" + style + "><a target=\"_blank\" href=\"" + rcu.getReactomeUrlForStableIdentifier(reactomId) + "\">" + reactomId + "</a></td>"; + + resultString += "<td" + style + ">" + status + "</td>"; + resultString += "<td" + style + ">" + df.format(result.getScore() * IProgressUpdater.MAX_PROGRESS) + "%</td>"; + resultString += "<td" + style + ">"; + for (ReactomePublication reference : result.getReaction().getLiteratureReferences()) { + if (reference instanceof ReactomeLiteratureReference) { + resultString += pubmedParser.getHtmlFullLinkForId(((ReactomeLiteratureReference) reference).getPubMedIdentifier()); + } else if (reference instanceof ReactomeURL) { + resultString += reference.getTitle() + "; " + ((ReactomeURL) reference).getUniformResourceLocator(); + } else { + throw new InvalidArgumentException("Unknown clas type: " + reference.getClass()); + } + } + resultString += "</td>"; + resultString += "</tr>"; + writer.println(resultString); + System.out.println(resultString); + } + + /** + * @return the pubmedParser + */ + public PubmedParser getPubmedParser() { + return pubmedParser; + } + + /** + * @param pubmedParser + * the pubmedParser to set + */ + public void setPubmedParser(PubmedParser pubmedParser) { + this.pubmedParser = pubmedParser; + } + + /** + * @return the reactionComparator + */ + public ReactionComparator getReactionComparator() { + return reactionComparator; + } + + /** + * @param reactionComparator + * the reactionComparator to set + */ + public void setReactionComparator(ReactionComparator reactionComparator) { + this.reactionComparator = reactionComparator; + } + + /** + * @return the rc + * @see #rc + */ + public DataSourceUpdater getRc() { + return rc; + } + + /** + * @param rc + * the rc to set + * @see #rc + */ + public void setRc(DataSourceUpdater rc) { + this.rc = rc; + } + + /** + * @return the rcu + * @see #rcu + */ + public ReactomeQueryUtil getRcu() { + return rcu; + } + + /** + * @param rcu + * the rcu to set + * @see #rcu + */ + public void setRcu(ReactomeQueryUtil rcu) { + this.rcu = rcu; + } + +} diff --git a/console/src/main/java/lcsb/mapviewer/run/Statistics.java b/console/src/main/java/lcsb/mapviewer/run/Statistics.java index 81930c619aca86358211ced48a3c86918ab904d9..90dbec74ede2b7aec6262b1aa251b2abd3e4ddd6 100644 --- a/console/src/main/java/lcsb/mapviewer/run/Statistics.java +++ b/console/src/main/java/lcsb/mapviewer/run/Statistics.java @@ -1,385 +1,387 @@ -package lcsb.mapviewer.run; - -import java.text.DecimalFormat; -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 lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.annotation.services.ModelAnnotator; -import lcsb.mapviewer.annotation.services.ProblematicAnnotation; -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.common.Configuration; -import lcsb.mapviewer.common.IProgressUpdater; -import lcsb.mapviewer.converter.ConverterParams; -import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; -import lcsb.mapviewer.model.map.Element; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.agregator.Compartment; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.model.map.species.ComplexSpecies; -import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.persist.ApplicationContextLoader; -import lcsb.mapviewer.persist.DbUtils; - -/** - * Class used for analyzing the CellDEsigner model and generating some statistic - * about it. - * - * @author Piotr Gawron - * - */ -public class Statistics { - /** - * Number of nanoseconds in second. - */ - private static final double NANOSECONDS_IN_SECOND = 1000000000.0; - - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(Statistics.class.getName()); - - /** - * Module that allows to annotate maps. - */ - @Autowired - private ModelAnnotator modelAnnotator; - - /** - * Local backend to the pubmed data. - */ - @Autowired - private PubmedParser pubmedBackend; - - /** - * Utils that help to manage the sessions in custom multithreaded - * implementation. - */ - @Autowired - private DbUtils dbUtils; - - /** - * Static main method used to run this stand alone code. - * - * @param args - * command line arguments - */ - public static void main(String[] args) { - try { - String[] modelFileNames = new String[] { "testFiles/pd_full/PD_160714_2/PD_160714_2.xml", // - "testFiles/pd_full/PD_160714_2/submaps/PARK2_substrates.xml", // - "testFiles/pd_full/PD_160714_2/submaps/Ubiquitin_proteasome_system.xml", // - "testFiles/pd_full/PD_160714_2/submaps/Fatty_acid_and_ketone_body_metabolism.xml", // - }; - - long startTime = System.nanoTime(); - - Statistics main = new Statistics(); - ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); - ApplicationContextLoader.injectDependencies(main); - - main.run(modelFileNames); - long endTime = System.nanoTime(); - - long duration = endTime - startTime; - double sec = duration / NANOSECONDS_IN_SECOND; - System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - /** - * Generate statistics. - * - * @param fileNames - * filenames for the models used for statistic generation - */ - public void run(String[] fileNames) { - dbUtils.createSessionForCurrentThread(); - List<Model> models = new ArrayList<>(); - try { - // String modelName = PdMapAnnotations.getLastPdFilename(); - CellDesignerXmlParser parser = new CellDesignerXmlParser(); - for (String name : fileNames) { - models.add(parser.createModel(new ConverterParams().filename(name))); - } - - IProgressUpdater updater = new IProgressUpdater() { - @Override - public void setProgress(double progress) { - logger.debug("Progress: " + progress); - } - }; - for (Model model : models) { - modelAnnotator.performAnnotations(model, updater); - } - // modelAnnotator.removeIncorrectAnnotations(model, updater); - - printStatistics(models); - - // printAnnotationInformation(model); - // - // PrintWriter writer = new PrintWriter("tmp.html", "UTF-8"); - // writer.println(createPubmedExportString(model)); - // writer.close(); - } catch (Exception e) { - logger.error(e.getMessage()); - e.printStackTrace(); - } - - dbUtils.closeSessionForCurrentThread(); - } - - /** - * Prints statistics for the model. - * - * @param models - * models under analysis - */ - protected void printStatistics(List<Model> models) { - int reactionNumber = 0; - for (Model model2 : models) { - reactionNumber += model2.getReactions().size(); - } - print("Reactions: "); - print(" number: " + reactionNumber); - Map<String, Set<String>> ids = new HashMap<String, Set<String>>(); - int pubmedReactions = 0; - for (Model model : models) { - for (Reaction reaction : model.getReactions()) { - for (MiriamData md : reaction.getMiriamData()) { - String type = md.getDataType().getCommonName(); - Set<String> set = ids.get(type); - if (set == null) { - set = new HashSet<String>(); - ids.put(type, set); - } - set.add(md.getResource()); - } - if (reaction.getMiriamData().size() == 1) { - if (reaction.getMiriamData().iterator().next().getDataType().equals(MiriamType.PUBMED)) { - pubmedReactions++; - } - } - } - } - - for (String string : ids.keySet()) { - print(" " + string + ": " + ids.get(string).size()); - } - print(" pubmed reactions: " + pubmedReactions); - - ids.clear(); - print("-----------------------------"); - print("Elements: "); - Set<String> names = new HashSet<String>(); - Map<String, Set<String>> typeNames = new HashMap<String, Set<String>>(); - - for (Model model : models) { - for (Element element : model.getElements()) { - if (element instanceof Species) { - names.add(((Species) element).getName()); - Set<String> tmp = typeNames.get(element.getClass().getName()); - if (tmp == null) { - tmp = new HashSet<String>(); - typeNames.put(element.getClass().getName(), tmp); - } - tmp.add(((Species) element).getName()); - for (MiriamData md : ((Species) element).getMiriamData()) { - String type = md.getDataType().getCommonName(); - Set<String> set = ids.get(type); - if (set == null) { - set = new HashSet<String>(); - ids.put(type, set); - } - set.add(md.getResource()); - } - } - } - } - print(" distinct names: " + names.size()); - - for (String string : ids.keySet()) { - print(" " + string + ": " + ids.get(string).size()); - } - - print("-----------------------------"); - print(" distinct elements types: "); - for (String string : typeNames.keySet()) { - print(" " + string + ": " + typeNames.get(string).size()); - } - - Set<String> set = new HashSet<String>(); - for (Model model : models) { - for (Compartment comp : model.getCompartments()) { - set.add(comp.getName()); - } - } - print(" compartments: " + set.size()); - } - - /** - * Prints information about inproper annotations. - * - * @param model - * model under analysis - */ - protected void printAnnotationInformation(Model model) { - print("-----------------------------"); - print("Improper annotations:"); - Collection<? extends ProblematicAnnotation> improper = modelAnnotator.findImproperAnnotations(model, new IProgressUpdater() { - @Override - public void setProgress(double progress) { - } - }, null); - for (ProblematicAnnotation improperAnnotation : improper) { - print(improperAnnotation.toString()); - } - print("-----------------------------"); - print("Missing annotations:"); - Collection<ProblematicAnnotation> missing = modelAnnotator.findMissingAnnotations(model, null); - for (ProblematicAnnotation improperAnnotation : missing) { - print(improperAnnotation.toString()); - } - print("-----------------------------"); - print("Complex annotations:"); - for (Element element : model.getElements()) { - if (element instanceof ComplexSpecies && element.getMiriamData().size() > 0) { - print(element.getClass().getSimpleName() + ";\t\tname=" + element.getName() + ";\t\tid=" + element.getElementId()); - } - } - print("-----------------------------"); - print("Pubmed annotated elements:"); - // Collection<? extends ProblematicAnnotation> pubmes = - // modelAnnotator.findPubmedAnnotatedElements(model); - // for (ProblematicAnnotation improperAnnotation : pubmes) { - // - // if (improperAnnotation.getObject() != null) { - // AnnotatedObject element = improperAnnotation.getObject(); - // String ids = ""; - // for (MiriamData md : improperAnnotation.getMd()) { - // ids += md.getResource() + ", "; - // } - // print(element.getClass().getSimpleName() + ";\t\tname=" + - // element.getName() + ";\t\tid=" + element.getElementId() + ";\t\tpubmed= " - // + ids); - // } - // } - } - - /** - * Prints line of the report. - * - * @param string - * text to print - */ - void print(String string) { - System.out.println(string); - } - - /** - * @return the modelAnnotator - */ - public ModelAnnotator getModelAnnotator() { - return modelAnnotator; - } - - /** - * @param modelAnnotator - * the modelAnnotator to set - */ - public void setModelAnnotator(ModelAnnotator modelAnnotator) { - this.modelAnnotator = modelAnnotator; - } - - /** - * Create tab separated string with information about pubmed articles used in - * the map. - * - * @param model - * analyzed model - * @return tab separated string with information about pubmed articles - */ - protected String createPubmedExportString(Model model) { - Map<String, List<String>> links = new HashMap<String, List<String>>(); - for (Element element : model.getElements()) { - for (MiriamData md : element.getMiriamData()) { - if (MiriamType.PUBMED.equals(md.getDataType())) { - List<String> list = links.get(md.getResource()); - if (list == null) { - list = new ArrayList<String>(); - links.put(md.getResource(), list); - } - String address = "<a href =\"" + Configuration.PUBLICALY_AVAILABLE_PD_MAP + "&search=species:" + element.getElementId() + "\">" + element.getName() - + "</a>"; - list.add(address); - } - } - } - - for (Reaction reaction : model.getReactions()) { - for (MiriamData md : reaction.getMiriamData()) { - if (MiriamType.PUBMED.equals(md.getDataType())) { - List<String> list = links.get(md.getResource()); - if (list == null) { - list = new ArrayList<String>(); - links.put(md.getResource(), list); - } - String address = "<a href =\"" + PdMapAnnotations.getLinkForReaction(reaction) + "\">Reaction: " + reaction.getIdReaction() + "</a>"; - list.add(address); - } - } - } - - StringBuilder result = new StringBuilder(); - - result.append("<html><head/><body><table>"); - for (String string : links.keySet()) { - Article article = pubmedBackend.getPubmedArticleById(Integer.valueOf(string)); - result.append("<tr><td><a href =\"" + article.getLink() + "\">" + string + "</a></td>"); - result.append("<td>" + article.getTitle() + "</td>"); - result.append("<td>" + article.getStringAuthors() + "</td>"); - result.append("<td>" + article.getJournal() + "</td>"); - result.append("<td>" + article.getYear() + "</td>"); - for (String str : links.get(string)) { - result.append("<td>"); - result.append(str); - result.append("</td>"); - } - result.append("</tr>\n"); - } - result.append("</table></body></html>"); - - return result.toString(); - } - - /** - * @return the pubmedBackend - * @see #pubmedBackend - */ - public PubmedParser getPubmedBackend() { - return pubmedBackend; - } - - /** - * @param pubmedBackend - * the pubmedBackend to set - * @see #pubmedBackend - */ - public void setPubmedBackend(PubmedParser pubmedBackend) { - this.pubmedBackend = pubmedBackend; - } - -} +package lcsb.mapviewer.run; + +import java.text.DecimalFormat; +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 lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.services.ModelAnnotator; +import lcsb.mapviewer.annotation.services.ProblematicAnnotation; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.common.IProgressUpdater; +import lcsb.mapviewer.converter.ConverterParams; +import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.model.map.Element; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.agregator.Compartment; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.species.ComplexSpecies; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.persist.ApplicationContextLoader; +import lcsb.mapviewer.persist.DbUtils; + +/** + * Class used for analyzing the CellDEsigner model and generating some statistic + * about it. + * + * @author Piotr Gawron + * + */ +public class Statistics { + /** + * Number of nanoseconds in second. + */ + private static final double NANOSECONDS_IN_SECOND = 1000000000.0; + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(Statistics.class.getName()); + + /** + * Module that allows to annotate maps. + */ + @Autowired + private ModelAnnotator modelAnnotator; + + /** + * Local backend to the pubmed data. + */ + @Autowired + private PubmedParser pubmedBackend; + + /** + * Utils that help to manage the sessions in custom multithreaded + * implementation. + */ + @Autowired + private DbUtils dbUtils; + + /** + * Static main method used to run this stand alone code. + * + * @param args + * command line arguments + */ + public static void main(String[] args) { + try { + String[] modelFileNames = new String[] { "testFiles/pd_full/PD_160714_2/PD_160714_2.xml", // + "testFiles/pd_full/PD_160714_2/submaps/PARK2_substrates.xml", // + "testFiles/pd_full/PD_160714_2/submaps/Ubiquitin_proteasome_system.xml", // + "testFiles/pd_full/PD_160714_2/submaps/Fatty_acid_and_ketone_body_metabolism.xml", // + }; + + long startTime = System.nanoTime(); + + Statistics main = new Statistics(); + ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); + ApplicationContextLoader.injectDependencies(main); + + main.run(modelFileNames); + long endTime = System.nanoTime(); + + long duration = endTime - startTime; + double sec = duration / NANOSECONDS_IN_SECOND; + System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * Generate statistics. + * + * @param fileNames + * filenames for the models used for statistic generation + */ + public void run(String[] fileNames) { + dbUtils.createSessionForCurrentThread(); + List<Model> models = new ArrayList<>(); + try { + // String modelName = PdMapAnnotations.getLastPdFilename(); + CellDesignerXmlParser parser = new CellDesignerXmlParser(); + for (String name : fileNames) { + models.add(parser.createModel(new ConverterParams().filename(name))); + } + + IProgressUpdater updater = new IProgressUpdater() { + @Override + public void setProgress(double progress) { + logger.debug("Progress: " + progress); + } + }; + for (Model model : models) { + modelAnnotator.performAnnotations(model, updater); + } + // modelAnnotator.removeIncorrectAnnotations(model, updater); + + printStatistics(models); + + // printAnnotationInformation(model); + // + // PrintWriter writer = new PrintWriter("tmp.html", "UTF-8"); + // writer.println(createPubmedExportString(model)); + // writer.close(); + } catch (Exception e) { + logger.error(e.getMessage()); + e.printStackTrace(); + } + + dbUtils.closeSessionForCurrentThread(); + } + + /** + * Prints statistics for the model. + * + * @param models + * models under analysis + */ + protected void printStatistics(List<Model> models) { + int reactionNumber = 0; + for (Model model2 : models) { + reactionNumber += model2.getReactions().size(); + } + print("Reactions: "); + print(" number: " + reactionNumber); + Map<String, Set<String>> ids = new HashMap<String, Set<String>>(); + int pubmedReactions = 0; + for (Model model : models) { + for (Reaction reaction : model.getReactions()) { + for (MiriamData md : reaction.getMiriamData()) { + String type = md.getDataType().getCommonName(); + Set<String> set = ids.get(type); + if (set == null) { + set = new HashSet<String>(); + ids.put(type, set); + } + set.add(md.getResource()); + } + if (reaction.getMiriamData().size() == 1) { + if (reaction.getMiriamData().iterator().next().getDataType().equals(MiriamType.PUBMED)) { + pubmedReactions++; + } + } + } + } + + for (String string : ids.keySet()) { + print(" " + string + ": " + ids.get(string).size()); + } + print(" pubmed reactions: " + pubmedReactions); + + ids.clear(); + print("-----------------------------"); + print("Elements: "); + Set<String> names = new HashSet<String>(); + Map<String, Set<String>> typeNames = new HashMap<String, Set<String>>(); + + for (Model model : models) { + for (Element element : model.getElements()) { + if (element instanceof Species) { + names.add(((Species) element).getName()); + Set<String> tmp = typeNames.get(element.getClass().getName()); + if (tmp == null) { + tmp = new HashSet<String>(); + typeNames.put(element.getClass().getName(), tmp); + } + tmp.add(((Species) element).getName()); + for (MiriamData md : ((Species) element).getMiriamData()) { + String type = md.getDataType().getCommonName(); + Set<String> set = ids.get(type); + if (set == null) { + set = new HashSet<String>(); + ids.put(type, set); + } + set.add(md.getResource()); + } + } + } + } + print(" distinct names: " + names.size()); + + for (String string : ids.keySet()) { + print(" " + string + ": " + ids.get(string).size()); + } + + print("-----------------------------"); + print(" distinct elements types: "); + for (String string : typeNames.keySet()) { + print(" " + string + ": " + typeNames.get(string).size()); + } + + Set<String> set = new HashSet<String>(); + for (Model model : models) { + for (Compartment comp : model.getCompartments()) { + set.add(comp.getName()); + } + } + print(" compartments: " + set.size()); + } + + /** + * Prints information about inproper annotations. + * + * @param model + * model under analysis + */ + protected void printAnnotationInformation(Model model) { + print("-----------------------------"); + print("Improper annotations:"); + Collection<? extends ProblematicAnnotation> improper = modelAnnotator.findImproperAnnotations(model, new IProgressUpdater() { + @Override + public void setProgress(double progress) { + } + }, null); + for (ProblematicAnnotation improperAnnotation : improper) { + print(improperAnnotation.toString()); + } + print("-----------------------------"); + print("Missing annotations:"); + Collection<ProblematicAnnotation> missing = modelAnnotator.findMissingAnnotations(model, null); + for (ProblematicAnnotation improperAnnotation : missing) { + print(improperAnnotation.toString()); + } + print("-----------------------------"); + print("Complex annotations:"); + for (Element element : model.getElements()) { + if (element instanceof ComplexSpecies && element.getMiriamData().size() > 0) { + print(element.getClass().getSimpleName() + ";\t\tname=" + element.getName() + ";\t\tid=" + element.getElementId()); + } + } + print("-----------------------------"); + print("Pubmed annotated elements:"); + // Collection<? extends ProblematicAnnotation> pubmes = + // modelAnnotator.findPubmedAnnotatedElements(model); + // for (ProblematicAnnotation improperAnnotation : pubmes) { + // + // if (improperAnnotation.getObject() != null) { + // AnnotatedObject element = improperAnnotation.getObject(); + // String ids = ""; + // for (MiriamData md : improperAnnotation.getMd()) { + // ids += md.getResource() + ", "; + // } + // print(element.getClass().getSimpleName() + ";\t\tname=" + + // element.getName() + ";\t\tid=" + element.getElementId() + ";\t\tpubmed= " + // + ids); + // } + // } + } + + /** + * Prints line of the report. + * + * @param string + * text to print + */ + void print(String string) { + System.out.println(string); + } + + /** + * @return the modelAnnotator + */ + public ModelAnnotator getModelAnnotator() { + return modelAnnotator; + } + + /** + * @param modelAnnotator + * the modelAnnotator to set + */ + public void setModelAnnotator(ModelAnnotator modelAnnotator) { + this.modelAnnotator = modelAnnotator; + } + + /** + * Create tab separated string with information about pubmed articles used in + * the map. + * + * @param model + * analyzed model + * @return tab separated string with information about pubmed articles + * @throws Exception + * thrown when there is a problem with pubmed + */ + protected String createPubmedExportString(Model model) throws Exception { + Map<String, List<String>> links = new HashMap<String, List<String>>(); + for (Element element : model.getElements()) { + for (MiriamData md : element.getMiriamData()) { + if (MiriamType.PUBMED.equals(md.getDataType())) { + List<String> list = links.get(md.getResource()); + if (list == null) { + list = new ArrayList<String>(); + links.put(md.getResource(), list); + } + String address = "<a href =\"" + Configuration.PUBLICALY_AVAILABLE_PD_MAP + "&search=species:" + element.getElementId() + "\">" + element.getName() + + "</a>"; + list.add(address); + } + } + } + + for (Reaction reaction : model.getReactions()) { + for (MiriamData md : reaction.getMiriamData()) { + if (MiriamType.PUBMED.equals(md.getDataType())) { + List<String> list = links.get(md.getResource()); + if (list == null) { + list = new ArrayList<String>(); + links.put(md.getResource(), list); + } + String address = "<a href =\"" + PdMapAnnotations.getLinkForReaction(reaction) + "\">Reaction: " + reaction.getIdReaction() + "</a>"; + list.add(address); + } + } + } + + StringBuilder result = new StringBuilder(); + + result.append("<html><head/><body><table>"); + for (String string : links.keySet()) { + Article article = pubmedBackend.getPubmedArticleById(Integer.valueOf(string)); + result.append("<tr><td><a href =\"" + article.getLink() + "\">" + string + "</a></td>"); + result.append("<td>" + article.getTitle() + "</td>"); + result.append("<td>" + article.getStringAuthors() + "</td>"); + result.append("<td>" + article.getJournal() + "</td>"); + result.append("<td>" + article.getYear() + "</td>"); + for (String str : links.get(string)) { + result.append("<td>"); + result.append(str); + result.append("</td>"); + } + result.append("</tr>\n"); + } + result.append("</table></body></html>"); + + return result.toString(); + } + + /** + * @return the pubmedBackend + * @see #pubmedBackend + */ + public PubmedParser getPubmedBackend() { + return pubmedBackend; + } + + /** + * @param pubmedBackend + * the pubmedBackend to set + * @see #pubmedBackend + */ + public void setPubmedBackend(PubmedParser pubmedBackend) { + this.pubmedBackend = pubmedBackend; + } + +} diff --git a/console/src/main/java/lcsb/mapviewer/run/UnknownReactionInReactome.java b/console/src/main/java/lcsb/mapviewer/run/UnknownReactionInReactome.java index 420da1a061ac241ebd2e16104b6b18bf9b5a5a7d..c0f17f66b1a0ec97cfde5ef6f8370eca9feb61ed 100644 --- a/console/src/main/java/lcsb/mapviewer/run/UnknownReactionInReactome.java +++ b/console/src/main/java/lcsb/mapviewer/run/UnknownReactionInReactome.java @@ -1,307 +1,304 @@ -package lcsb.mapviewer.run; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; -import lcsb.mapviewer.commands.CreateHierarchyCommand; -import lcsb.mapviewer.converter.ConverterParams; -import lcsb.mapviewer.converter.graphics.MapGenerator; -import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.layout.alias.ArtifitialCompartmentAlias; -import lcsb.mapviewer.model.map.layout.alias.CompartmentAlias; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.model.map.reaction.ReactionNode; -import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.persist.ApplicationContextLoader; -import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject; -import lcsb.mapviewer.reactome.utils.DataFormatter; -import lcsb.mapviewer.reactome.utils.ReactomeQueryUtil; -import lcsb.mapviewer.reactome.utils.comparators.MatchResult; - -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * This class prepare report of data that are not included in reactome and maybe - * should be added. - * - * @author Piotr Gawron - * - */ -public class UnknownReactionInReactome { - /** - * Number of nanoseconds in a second. - */ - private static final double NANOSECONDS_IN_SECOND = 1000000000.0; - - /** - * Model used for generating raport. - */ - private Model model; - - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(UnknownReactionInReactome.class); - - /** - * Util class used for manipulating information in reactome objects. - */ - @Autowired - private ReactomeQueryUtil rcu; - - /** - * Formatter used for reaction comparison. - */ - @Autowired - private DataFormatter dataFormatter; - - /** - * Class used for accessing data in pubmed database. - */ - @Autowired - private PubmedParser pubmedParser; - - /** - * Static main method used to run this stand alone code. - * - * @param args - * command line arguments - */ - public static void main(String[] args) { - long startTime = System.nanoTime(); - PropertyConfigurator.configure("src/main/webapp/WEB-INF/resources/log4j.properties"); - UnknownReactionInReactome main = new UnknownReactionInReactome(); - ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); - ApplicationContextLoader.injectDependencies(main); - main.run(); - long endTime = System.nanoTime(); - - long duration = endTime - startTime; - double sec = duration / NANOSECONDS_IN_SECOND; - System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); - } - - /** - * Executes comparison between model and reactome to generate report. - */ - public void run() { - try { - MapGenerator mg = new MapGenerator(); - model = new CellDesignerXmlParser().createModel(new ConverterParams().filename(PdMapAnnotations.getLastPdFilename())); - new CreateHierarchyCommand(model, mg.computeZoomLevels(model), mg.computeZoomFactor(model)).execute(); - List<String> ids = new ArrayList<String>(); - for (Reaction reaction : model.getReactions()) { - if (rcu.getReactomeIdentifierForReaction(reaction) == null) { - ids.add(reaction.getIdReaction()); - } - } - Collections.sort(ids); - printHeader(); - List<MatchResult> results = new ArrayList<MatchResult>(); - for (String string : ids) { - boolean unknown = true; - boolean pubmed = false; - Reaction reaction = model.getReactionByReactionId(string); - for (MiriamData md : reaction.getMiriamData()) { - if (md.getDataType().equals(MiriamType.PUBMED)) { - pubmed = true; - ReactomeDatabaseObject obj = rcu.getLiteratureReferenceByPubMedId(Integer.parseInt(md.getResource())); - if (obj != null) { - unknown = false; - } - } - } - if (pubmed && unknown) { - MatchResult matchResult = new MatchResult(); - matchResult.setLocalReaction(reaction); - for (ReactionNode node : reaction.getReactants()) { - matchResult.addInvalidLocalInput((Species) node.getElement()); - } - for (ReactionNode node : reaction.getProducts()) { - matchResult.addInvalidLocalOutput((Species) node.getElement()); - } - for (ReactionNode node : reaction.getModifiers()) { - matchResult.addInvalidLocalModifier((Species) node.getElement()); - } - results.add(matchResult); - printResult(matchResult); - } - } - printFooter(results); - - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - - } - - /** - * Prints report footer. - * - * @param results - * results used in the report - */ - private void printFooter(List<MatchResult> results) { - - writer.println("</table>"); - writer.println("Reactions: " + results.size()); - writer.println("</body></html>"); - - writer.close(); - } - - /** - * Object to which the report is written. - */ - private PrintWriter writer; - - /** - * Creates report stream and prints header of the report. - * - * @throws FileNotFoundException - * if there is a problem with creating report file - * @throws UnsupportedEncodingException - * thrown when there are problems with encoding - */ - private void printHeader() throws FileNotFoundException, UnsupportedEncodingException { - writer = new PrintWriter("out/report/report-export.html", "UTF-8"); - writer.println("<html><head></head><body>"); - writer.println("<table cellspacing=\"0\""); - - String resultString = "<tr>"; - resultString += "<td" + style + ">Reaction</td>"; - resultString += "<td" + style + ">Pubmed ids</td>"; - resultString += "<td" + style + ">Ontologies</td>"; - resultString += "<td" + style + ">Input</td>"; - resultString += "<td" + style + ">Modifier</td>"; - resultString += "<td" + style + ">Output</td>"; - resultString += "</tr>"; - writer.println(resultString); - - } - - /** - * Style used by report cells. - */ - private String style = " style=\"border-width:1;border-style:solid;border-color:#000000;\" "; - - /** - * Prints result row. - * - * @param result - * result to be printed - * @throws IOException - * @throws AnnotatorException - */ - private void printResult(MatchResult result) throws IOException, AnnotatorException { - - Set<String> ontologies = new HashSet<String>(); - - for (CompartmentAlias alias : model.getCompartmentsAliases()) { - for (ReactionNode node : result.getLocalReaction().getReactionNodes()) { - if (alias.contains(node.getAlias())) { - if (alias instanceof ArtifitialCompartmentAlias) { - ontologies.add(((ArtifitialCompartmentAlias) alias).getTitle()); - } else { - ontologies.add(alias.getCompartment().getName()); - } - break; - } - } - } - - String color = "#FFFFFF"; - String resultString = "<tr bgcolor = \"" + color + "\">"; - String reactionId = result.getLocalReaction().getIdReaction(); - resultString += "<td" + style + "><a target=\"_blank\" href=\"" + PdMapAnnotations.getLinkForReaction(result.getLocalReaction()) + "\">" + reactionId - + "</a></td>"; - - String pubmed = ""; - for (MiriamData md : result.getLocalReaction().getMiriamData()) { - if (md.getDataType().equals(MiriamType.PUBMED)) { - pubmed += pubmedParser.getHtmlFullLinkForId(Integer.valueOf(md.getResource()), false) + "<br/>"; - } - } - - resultString += "<td" + style + ">" + pubmed + "</td>"; - - String ont = ""; - for (String string : ontologies) { - if (!ont.equals("")) { - ont += "<hr/>"; - } - ont += string; - } - resultString += "<td" + style + ">" + ont + "</td>"; - - resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalInputString(result) + " </td>"; - resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalModifierString(result) + " </td>"; - resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalOutputString(result) + " </td>"; - resultString += "</tr>"; - writer.println(resultString); - System.out.println(resultString); - } - - /** - * @return the dataFormatter - */ - public DataFormatter getDataFormatter() { - return dataFormatter; - } - - /** - * @param dataFormatter - * the dataFormatter to set - */ - public void setDataFormatter(DataFormatter dataFormatter) { - this.dataFormatter = dataFormatter; - } - - /** - * @return the pubmedParser - */ - public PubmedParser getPubmedParser() { - return pubmedParser; - } - - /** - * @param pubmedParser - * the pubmedParser to set - */ - public void setPubmedParser(PubmedParser pubmedParser) { - this.pubmedParser = pubmedParser; - } - - /** - * @return the rcu - * @see #rcu - */ - public ReactomeQueryUtil getRcu() { - return rcu; - } - - /** - * @param rcu - * the rcu to set - * @see #rcu - */ - public void setRcu(ReactomeQueryUtil rcu) { - this.rcu = rcu; - } - -} +package lcsb.mapviewer.run; + +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.commands.CreateHierarchyCommand; +import lcsb.mapviewer.converter.ConverterParams; +import lcsb.mapviewer.converter.graphics.MapGenerator; +import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.layout.alias.ArtifitialCompartmentAlias; +import lcsb.mapviewer.model.map.layout.alias.CompartmentAlias; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.reaction.ReactionNode; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.persist.ApplicationContextLoader; +import lcsb.mapviewer.reactome.model.ReactomeDatabaseObject; +import lcsb.mapviewer.reactome.utils.DataFormatter; +import lcsb.mapviewer.reactome.utils.ReactomeQueryUtil; +import lcsb.mapviewer.reactome.utils.comparators.MatchResult; + +/** + * This class prepare report of data that are not included in reactome and maybe + * should be added. + * + * @author Piotr Gawron + * + */ +public class UnknownReactionInReactome { + /** + * Number of nanoseconds in a second. + */ + private static final double NANOSECONDS_IN_SECOND = 1000000000.0; + + /** + * Model used for generating raport. + */ + private Model model; + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(UnknownReactionInReactome.class); + + /** + * Util class used for manipulating information in reactome objects. + */ + @Autowired + private ReactomeQueryUtil rcu; + + /** + * Formatter used for reaction comparison. + */ + @Autowired + private DataFormatter dataFormatter; + + /** + * Class used for accessing data in pubmed database. + */ + @Autowired + private PubmedParser pubmedParser; + + /** + * Static main method used to run this stand alone code. + * + * @param args + * command line arguments + */ + public static void main(String[] args) { + long startTime = System.nanoTime(); + PropertyConfigurator.configure("src/main/webapp/WEB-INF/resources/log4j.properties"); + UnknownReactionInReactome main = new UnknownReactionInReactome(); + ApplicationContextLoader.loadApplicationContext("consoleApplicationContext.xml"); + ApplicationContextLoader.injectDependencies(main); + main.run(); + long endTime = System.nanoTime(); + + long duration = endTime - startTime; + double sec = duration / NANOSECONDS_IN_SECOND; + System.out.println("Duration: " + new DecimalFormat("#.###").format(sec) + "s"); + } + + /** + * Executes comparison between model and reactome to generate report. + */ + public void run() { + try { + MapGenerator mg = new MapGenerator(); + model = new CellDesignerXmlParser().createModel(new ConverterParams().filename(PdMapAnnotations.getLastPdFilename())); + new CreateHierarchyCommand(model, mg.computeZoomLevels(model), mg.computeZoomFactor(model)).execute(); + List<String> ids = new ArrayList<String>(); + for (Reaction reaction : model.getReactions()) { + if (rcu.getReactomeIdentifierForReaction(reaction) == null) { + ids.add(reaction.getIdReaction()); + } + } + Collections.sort(ids); + printHeader(); + List<MatchResult> results = new ArrayList<MatchResult>(); + for (String string : ids) { + boolean unknown = true; + boolean pubmed = false; + Reaction reaction = model.getReactionByReactionId(string); + for (MiriamData md : reaction.getMiriamData()) { + if (md.getDataType().equals(MiriamType.PUBMED)) { + pubmed = true; + ReactomeDatabaseObject obj = rcu.getLiteratureReferenceByPubMedId(Integer.parseInt(md.getResource())); + if (obj != null) { + unknown = false; + } + } + } + if (pubmed && unknown) { + MatchResult matchResult = new MatchResult(); + matchResult.setLocalReaction(reaction); + for (ReactionNode node : reaction.getReactants()) { + matchResult.addInvalidLocalInput((Species) node.getElement()); + } + for (ReactionNode node : reaction.getProducts()) { + matchResult.addInvalidLocalOutput((Species) node.getElement()); + } + for (ReactionNode node : reaction.getModifiers()) { + matchResult.addInvalidLocalModifier((Species) node.getElement()); + } + results.add(matchResult); + printResult(matchResult); + } + } + printFooter(results); + + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + + } + + /** + * Prints report footer. + * + * @param results + * results used in the report + */ + private void printFooter(List<MatchResult> results) { + + writer.println("</table>"); + writer.println("Reactions: " + results.size()); + writer.println("</body></html>"); + + writer.close(); + } + + /** + * Object to which the report is written. + */ + private PrintWriter writer; + + /** + * Creates report stream and prints header of the report. + * + * @throws FileNotFoundException + * if there is a problem with creating report file + * @throws UnsupportedEncodingException + * thrown when there are problems with encoding + */ + private void printHeader() throws FileNotFoundException, UnsupportedEncodingException { + writer = new PrintWriter("out/report/report-export.html", "UTF-8"); + writer.println("<html><head></head><body>"); + writer.println("<table cellspacing=\"0\""); + + String resultString = "<tr>"; + resultString += "<td" + style + ">Reaction</td>"; + resultString += "<td" + style + ">Pubmed ids</td>"; + resultString += "<td" + style + ">Ontologies</td>"; + resultString += "<td" + style + ">Input</td>"; + resultString += "<td" + style + ">Modifier</td>"; + resultString += "<td" + style + ">Output</td>"; + resultString += "</tr>"; + writer.println(resultString); + + } + + /** + * Style used by report cells. + */ + private String style = " style=\"border-width:1;border-style:solid;border-color:#000000;\" "; + + /** + * Prints result row. + * + * @param result + * result to be printed + * @throws Exception thrown when there is a problem with printing + */ + private void printResult(MatchResult result) throws Exception { + + Set<String> ontologies = new HashSet<String>(); + + for (CompartmentAlias alias : model.getCompartmentsAliases()) { + for (ReactionNode node : result.getLocalReaction().getReactionNodes()) { + if (alias.contains(node.getAlias())) { + if (alias instanceof ArtifitialCompartmentAlias) { + ontologies.add(((ArtifitialCompartmentAlias) alias).getTitle()); + } else { + ontologies.add(alias.getCompartment().getName()); + } + break; + } + } + } + + String color = "#FFFFFF"; + String resultString = "<tr bgcolor = \"" + color + "\">"; + String reactionId = result.getLocalReaction().getIdReaction(); + resultString += "<td" + style + "><a target=\"_blank\" href=\"" + PdMapAnnotations.getLinkForReaction(result.getLocalReaction()) + "\">" + reactionId + + "</a></td>"; + + String pubmed = ""; + for (MiriamData md : result.getLocalReaction().getMiriamData()) { + if (md.getDataType().equals(MiriamType.PUBMED)) { + pubmed += pubmedParser.getHtmlFullLinkForId(Integer.valueOf(md.getResource()), false) + "<br/>"; + } + } + + resultString += "<td" + style + ">" + pubmed + "</td>"; + + String ont = ""; + for (String string : ontologies) { + if (!ont.equals("")) { + ont += "<hr/>"; + } + ont += string; + } + resultString += "<td" + style + ">" + ont + "</td>"; + + resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalInputString(result) + " </td>"; + resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalModifierString(result) + " </td>"; + resultString += "<td" + style + ">" + dataFormatter.getInvalidLocalOutputString(result) + " </td>"; + resultString += "</tr>"; + writer.println(resultString); + System.out.println(resultString); + } + + /** + * @return the dataFormatter + */ + public DataFormatter getDataFormatter() { + return dataFormatter; + } + + /** + * @param dataFormatter + * the dataFormatter to set + */ + public void setDataFormatter(DataFormatter dataFormatter) { + this.dataFormatter = dataFormatter; + } + + /** + * @return the pubmedParser + */ + public PubmedParser getPubmedParser() { + return pubmedParser; + } + + /** + * @param pubmedParser + * the pubmedParser to set + */ + public void setPubmedParser(PubmedParser pubmedParser) { + this.pubmedParser = pubmedParser; + } + + /** + * @return the rcu + * @see #rcu + */ + public ReactomeQueryUtil getRcu() { + return rcu; + } + + /** + * @param rcu + * the rcu to set + * @see #rcu + */ + public void setRcu(ReactomeQueryUtil rcu) { + this.rcu = rcu; + } + +} diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ModelService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ModelService.java index 6506dbbcd87d7812d3381246fd6797aad2ab07d3..28375a5c04c7d9b3de1188d10d197a16a1a2812e 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/ModelService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/ModelService.java @@ -1,515 +1,520 @@ -package lcsb.mapviewer.services.impl; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; - -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.annotation.services.MeSHParser; -import lcsb.mapviewer.annotation.services.MiriamConnector; -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.annotation.services.TaxonomyBackend; -import lcsb.mapviewer.annotation.services.TaxonomySearchException; -import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; -import lcsb.mapviewer.commands.CopyCommand; -import lcsb.mapviewer.common.IProgressUpdater; -import lcsb.mapviewer.common.Pair; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.model.map.Element; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.layout.Layout; -import lcsb.mapviewer.model.map.layout.alias.Alias; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.model.ModelData; -import lcsb.mapviewer.model.map.model.ModelFullIndexed; -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.model.user.User; -import lcsb.mapviewer.persist.dao.map.ModelDao; -import lcsb.mapviewer.services.interfaces.ILayoutService; -import lcsb.mapviewer.services.interfaces.IModelService; -import lcsb.mapviewer.services.search.data.FullAliasView; -import lcsb.mapviewer.services.search.data.FullAliasViewFactory; -import lcsb.mapviewer.services.search.data.LightAliasView; -import lcsb.mapviewer.services.search.data.LightAliasViewFactory; -import lcsb.mapviewer.services.search.data.LightReactionView; -import lcsb.mapviewer.services.view.LayoutView; -import lcsb.mapviewer.services.view.ModelView; -import lcsb.mapviewer.services.view.ModelViewFactory; -import lcsb.mapviewer.services.view.ProjectView; - -/** - * Implementation of the service that manages models. - * - * @author Piotr Gawron - * - */ -@Transactional(value = "txManager") -public class ModelService implements IModelService { - - /** - * Default class logger. - */ - private Logger logger = Logger.getLogger(ModelService.class); - - /** - * List of cached models. - */ - private static Map<String, Model> models = new HashMap<String, Model>(); - - /** - * List of models that are currently being loaded from databsae. - */ - private static Set<String> modelsInLoadStage = new HashSet<>(); - - /** - * Data access object for models. - */ - @Autowired - private ModelDao modelDao; - - /** - * Object allowing access to the mesh database. - */ - @Autowired - private MeSHParser meshParser; - - /** - * Local backend to the pubmed data. - */ - @Autowired - private PubmedParser backend; - - /** - * Service used for managing layouts. - */ - @Autowired - private ILayoutService layoutService; - - /** - * Connector used for accessing data from miriam registry. - */ - @Autowired - private MiriamConnector miriamConnector; - - /** - * Factory object used for creation of {@link ModelView} elements. - */ - @Autowired - private ModelViewFactory modelViewFactory; - - /** - * Factory used to create {@link FullAliasView} elements. - */ - @Autowired - private FullAliasViewFactory fullAliasViewFactory; - - /** - * Access point and parser for the online ctd database. - */ - @Autowired - private TaxonomyBackend taxonomyBackend; - - @Override - public Model getLastModelByProjectId(String projectName) { - if (projectName == null) { - return null; - } - - // check if model is being loaded by another thread - boolean waitForModel = false; - do { - synchronized (modelsInLoadStage) { - waitForModel = modelsInLoadStage.contains(projectName); - } - // if model is being loaded then wait until it's loaded - if (waitForModel) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - logger.fatal(e, e); - } - } - } while (waitForModel); - - Model model = models.get(projectName); - if (model == null) { - try { - // mark model as being load stage, so other threads that want to access - // it will wait - synchronized (modelsInLoadStage) { - modelsInLoadStage.add(projectName); - } - logger.debug("Unknown model, trying to load the model into memory."); - - ModelData modelData = modelDao.getLastModelForProjectIdentifier(projectName, false); - - if (modelData == null) { - logger.debug("Model doesn't exist"); - return null; - } - logger.debug("Model loaded from db."); - model = new ModelFullIndexed(modelData); - - // this is a trick to load all required subelements of the model... ;/ - // lets copy model - it will access all elements... - new CopyCommand(model).execute(); - - logger.debug("Model loaded successfullly"); - models.put(projectName, model); - } finally { - // model is not being loaded anymore - synchronized (modelsInLoadStage) { - modelsInLoadStage.remove(projectName); - } - } - } - return model; - } - - @Override - public void cacheAllPubmedIds(Model model, IProgressUpdater updater) { - logger.debug("Caching pubmed ids..."); - if (model != null) { - Set<Integer> pubmedIds = new HashSet<Integer>(); - - for (Element element : model.getElements()) { - if (element instanceof Species) { - for (MiriamData md : ((Species) element).getMiriamData()) { - if (MiriamType.PUBMED.equals(md.getDataType())) { - try { - pubmedIds.add(Integer.parseInt(md.getResource())); - } catch (NumberFormatException e) { - logger.error("Problem with parsing: " + e.getMessage(), e); - } - } - } - } - } - for (Reaction reaction : model.getReactions()) { - for (MiriamData md : reaction.getMiriamData()) { - if (MiriamType.PUBMED.equals(md.getDataType())) { - try { - pubmedIds.add(Integer.parseInt(md.getResource())); - } catch (NumberFormatException e) { - logger.error("Problem with parsing: " + e.getMessage(), e); - } - } - } - } - double amount = pubmedIds.size(); - double counter = 0; - for (Integer id : pubmedIds) { - Article art = backend.getPubmedArticleById(id); - if (art == null) { - logger.warn("Cannot find pubmed article. Pubmed_id = " + id); - } - counter++; - updater.setProgress(IProgressUpdater.MAX_PROGRESS * counter / amount); - } - } - logger.debug("Caching finished"); - } - - @Override - public void updateModel(ModelData model, ProjectView selectedProject) { - - for (Model cachedModel : models.values()) { - if (cachedModel.getId().equals(selectedProject.getModelId())) { - setModel(cachedModel.getModelData(), selectedProject); - } - } - setModel(model, selectedProject); - modelDao.update(model); - } - - /** - * Sets the data from selectedProject into model. - * - * @param model - * destination of the data - * @param selectedProject - * source of the data - */ - private void setModel(ModelData model, ProjectView selectedProject) { - model.setNotes(selectedProject.getDescription()); - model.setMapVersion(selectedProject.getVersion()); - model.setNotifyEmail(selectedProject.getNotifyEmail()); - List<Layout> toRemove = new ArrayList<Layout>(); - for (Layout layout : model.getLayouts()) { - boolean exists = false; - for (LayoutView row : selectedProject.getLayouts()) { - if (layout.getId() == row.getIdObject()) { - exists = true; - // don't allow client side to edit layouts - // layout.setDirectory(row.getDirectory()); - layout.setTitle(row.getName()); - layout.setDescription(row.getDescription()); - } - } - if (!exists) { - toRemove.add(layout); - } - } - model.getLayouts().removeAll(toRemove); - - MiriamData disease = null; - if (selectedProject.getNewDiseaseName() != null) { - disease = new MiriamData(MiriamType.MESH_2012, selectedProject.getNewDiseaseName()); - } - - try { - if (meshParser.isValidMeshId(disease)) { - model.getProject().setDisease(disease); - } else { - model.getProject().setDisease(null); - selectedProject.setNewDiseaseName(null); - } - } catch (AnnotatorException e) { - logger.warn("Problem with accessing mesh db"); - } - - if (model.getProject() != null) { - MiriamData organism = null; - if (selectedProject.getNewOrganismName() != null && !selectedProject.getNewOrganismName().isEmpty()) { - organism = new MiriamData(MiriamType.TAXONOMY, selectedProject.getNewOrganismName()); - } - - try { - if (taxonomyBackend.getNameForTaxonomy(organism) != null) { - model.getProject().setOrganism(organism); - } else { - model.getProject().setOrganism(null); - } - } catch (TaxonomySearchException e) { - logger.error("Problem with accessing taxonomy db", e); - model.getProject().setOrganism(null); - } - } - - } - - @Override - public void removeModelFromCache(Model model) { - models.remove(model.getProject().getProjectId()); - - } - - /** - * @return the modelDao - * @see #modelDao - */ - public ModelDao getModelDao() { - return modelDao; - } - - /** - * @param modelDao - * the modelDao to set - * @see #modelDao - */ - public void setModelDao(ModelDao modelDao) { - this.modelDao = modelDao; - } - - /** - * @return the backend - * @see #backend - */ - public PubmedParser getBackend() { - return backend; - } - - /** - * @param backend - * the backend to set - * @see #backend - */ - public void setBackend(PubmedParser backend) { - this.backend = backend; - } - - @Override - public void cacheAllMiriamLinks(Model model, IProgressUpdater updater) { - logger.debug("Caching miriam ids..."); - if (model != null) { - Set<MiriamData> pubmedIds = new HashSet<MiriamData>(); - - for (Element element : model.getElements()) { - pubmedIds.addAll(element.getMiriamData()); - } - for (Reaction reaction : model.getReactions()) { - pubmedIds.addAll(reaction.getMiriamData()); - } - double amount = pubmedIds.size(); - double counter = 0; - for (MiriamData md : pubmedIds) { - miriamConnector.getUrlString(md); - counter++; - updater.setProgress(IProgressUpdater.MAX_PROGRESS * counter / amount); - } - } - logger.debug("Caching finished"); - - } - - @Override - public ModelView getModelView(Model model, User user) { - ModelView result = modelViewFactory.create(model); - if (user != null) { - result.setCustomLayouts(layoutService.getCustomLayouts(model, user)); - for (ModelView view : result.getSubmodels()) { - view.setCustomLayouts(layoutService.getCustomLayouts(model.getSubmodelById(view.getIdObject()), user)); - } - } - return result; - } - - @Override - public void removeModelFromCache(ModelData model) { - models.remove(model.getProject().getProjectId()); - } - - /** - * @return the layoutService - * @see #layoutService - */ - public ILayoutService getLayoutService() { - return layoutService; - } - - /** - * @param layoutService - * the layoutService to set - * @see #layoutService - */ - public void setLayoutService(ILayoutService layoutService) { - this.layoutService = layoutService; - } - - @Override - public void removeModelFromCacheByProjectId(String projectId) { - models.remove(projectId); - } - - @Override - public List<LightAliasView> getLightAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { - LightAliasViewFactory lightAliasViewFactory = new LightAliasViewFactory(); - List<LightAliasView> result = lightAliasViewFactory.createList(getAliasesByIds(model, identifiers)); - return result; - } - - /** - * Returns list of {@link Alias aliases} for given identifiers. - * - * @param model - * model where aliases are located - * @param identifiers - * list of alias identifiers in a given submodel. Every {@link Pair} - * contains information about {@link Model#getId() model identifier} - * (in {@link Pair#left}) and - * {@link lcsb.mapviewer.model.map.layout.alias.Alias#getId() alias - * identifier} (in {@link Pair#right}). - * @return list of {@link Alias aliases} for given identifiers - */ - private List<Alias> getAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { - Map<Integer, Set<Integer>> identifiersForMap = new HashMap<>(); - for (Pair<Integer, Integer> pair : identifiers) { - Set<Integer> set = identifiersForMap.get(pair.getLeft()); - if (set == null) { - set = new HashSet<>(); - identifiersForMap.put(pair.getLeft(), set); - } - set.add(pair.getRight()); - } - - List<Alias> result = new ArrayList<>(); - List<Model> models = new ArrayList<>(); - models.add(model); - models.addAll(model.getSubmodels()); - for (Model model2 : models) { - Set<Integer> set = identifiersForMap.get(model2.getModelData().getId()); - if (set != null) { - for (Alias alias : model2.getAliases()) { - if (set.contains(alias.getId())) { - result.add(alias); - set.remove(alias.getId()); - } - if (set.size() == 0) { - break; - } - } - if (set.size() > 0) { - Integer aliasId = set.iterator().next(); - throw new InvalidArgumentException("Cannot find alias (id: " + aliasId + ") in a model (id: " + model2.getModelData().getId() + ")"); - } - identifiersForMap.remove(model2.getModelData().getId()); - } - } - if (identifiersForMap.keySet().size() > 0) { - Integer modelId = identifiersForMap.keySet().iterator().next(); - Integer aliasId = identifiersForMap.get(modelId).iterator().next(); - throw new InvalidArgumentException("Cannot find alias (id: " + aliasId + ") in a model (id: " + modelId + "). Model doesn't exist."); - } - return result; - } - - @Override - public List<LightReactionView> getLightReactionsByIds(Model model, List<Pair<Integer, Integer>> identifiers) { - - Map<Integer, Set<Integer>> identifiersForMap = new HashMap<>(); - for (Pair<Integer, Integer> pair : identifiers) { - Set<Integer> set = identifiersForMap.get(pair.getLeft()); - if (set == null) { - set = new HashSet<>(); - identifiersForMap.put(pair.getLeft(), set); - } - set.add(pair.getRight()); - } - - List<LightReactionView> result = new ArrayList<>(); - List<Model> models = new ArrayList<>(); - models.add(model); - models.addAll(model.getSubmodels()); - for (Model model2 : models) { - Set<Integer> set = identifiersForMap.get(model2.getModelData().getId()); - if (set != null) { - for (Reaction reaction : model2.getReactions()) { - if (set.contains(reaction.getId())) { - result.add(new LightReactionView(reaction)); - set.remove(reaction.getId()); - } - if (set.size() == 0) { - break; - } - } - if (set.size() > 0) { - Integer aliasId = set.iterator().next(); - throw new InvalidArgumentException("Cannot find reaction (id: " + aliasId + ") in a model (id: " + model2.getModelData().getId() + ")"); - } - identifiersForMap.remove(model2.getModelData().getId()); - } - } - if (identifiersForMap.keySet().size() > 0) { - Integer modelId = identifiersForMap.keySet().iterator().next(); - Integer aliasId = identifiersForMap.get(modelId).iterator().next(); - throw new InvalidArgumentException("Cannot find reaction (id: " + aliasId + ") in a model (id: " + modelId + "). Model doesn't exist."); - } - return result; - } - - @Override - public List<FullAliasView> getFullAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { - List<FullAliasView> result = fullAliasViewFactory.createList(getAliasesByIds(model, identifiers)); - return result; - } - -} +package lcsb.mapviewer.services.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.services.MeSHParser; +import lcsb.mapviewer.annotation.services.MiriamConnector; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.annotation.services.PubmedSearchException; +import lcsb.mapviewer.annotation.services.TaxonomyBackend; +import lcsb.mapviewer.annotation.services.TaxonomySearchException; +import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; +import lcsb.mapviewer.commands.CopyCommand; +import lcsb.mapviewer.common.IProgressUpdater; +import lcsb.mapviewer.common.Pair; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.model.map.Element; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.layout.Layout; +import lcsb.mapviewer.model.map.layout.alias.Alias; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelData; +import lcsb.mapviewer.model.map.model.ModelFullIndexed; +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.persist.dao.map.ModelDao; +import lcsb.mapviewer.services.interfaces.ILayoutService; +import lcsb.mapviewer.services.interfaces.IModelService; +import lcsb.mapviewer.services.search.data.FullAliasView; +import lcsb.mapviewer.services.search.data.FullAliasViewFactory; +import lcsb.mapviewer.services.search.data.LightAliasView; +import lcsb.mapviewer.services.search.data.LightAliasViewFactory; +import lcsb.mapviewer.services.search.data.LightReactionView; +import lcsb.mapviewer.services.view.LayoutView; +import lcsb.mapviewer.services.view.ModelView; +import lcsb.mapviewer.services.view.ModelViewFactory; +import lcsb.mapviewer.services.view.ProjectView; + +/** + * Implementation of the service that manages models. + * + * @author Piotr Gawron + * + */ +@Transactional(value = "txManager") +public class ModelService implements IModelService { + + /** + * Default class logger. + */ + private Logger logger = Logger.getLogger(ModelService.class); + + /** + * List of cached models. + */ + private static Map<String, Model> models = new HashMap<String, Model>(); + + /** + * List of models that are currently being loaded from databsae. + */ + private static Set<String> modelsInLoadStage = new HashSet<>(); + + /** + * Data access object for models. + */ + @Autowired + private ModelDao modelDao; + + /** + * Object allowing access to the mesh database. + */ + @Autowired + private MeSHParser meshParser; + + /** + * Local backend to the pubmed data. + */ + @Autowired + private PubmedParser backend; + + /** + * Service used for managing layouts. + */ + @Autowired + private ILayoutService layoutService; + + /** + * Connector used for accessing data from miriam registry. + */ + @Autowired + private MiriamConnector miriamConnector; + + /** + * Factory object used for creation of {@link ModelView} elements. + */ + @Autowired + private ModelViewFactory modelViewFactory; + + /** + * Factory used to create {@link FullAliasView} elements. + */ + @Autowired + private FullAliasViewFactory fullAliasViewFactory; + + /** + * Access point and parser for the online ctd database. + */ + @Autowired + private TaxonomyBackend taxonomyBackend; + + @Override + public Model getLastModelByProjectId(String projectName) { + if (projectName == null) { + return null; + } + + // check if model is being loaded by another thread + boolean waitForModel = false; + do { + synchronized (modelsInLoadStage) { + waitForModel = modelsInLoadStage.contains(projectName); + } + // if model is being loaded then wait until it's loaded + if (waitForModel) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + logger.fatal(e, e); + } + } + } while (waitForModel); + + Model model = models.get(projectName); + if (model == null) { + try { + // mark model as being load stage, so other threads that want to access + // it will wait + synchronized (modelsInLoadStage) { + modelsInLoadStage.add(projectName); + } + logger.debug("Unknown model, trying to load the model into memory."); + + ModelData modelData = modelDao.getLastModelForProjectIdentifier(projectName, false); + + if (modelData == null) { + logger.debug("Model doesn't exist"); + return null; + } + logger.debug("Model loaded from db."); + model = new ModelFullIndexed(modelData); + + // this is a trick to load all required subelements of the model... ;/ + // lets copy model - it will access all elements... + new CopyCommand(model).execute(); + + logger.debug("Model loaded successfullly"); + models.put(projectName, model); + } finally { + // model is not being loaded anymore + synchronized (modelsInLoadStage) { + modelsInLoadStage.remove(projectName); + } + } + } + return model; + } + + @Override + public void cacheAllPubmedIds(Model model, IProgressUpdater updater) { + logger.debug("Caching pubmed ids..."); + if (model != null) { + Set<Integer> pubmedIds = new HashSet<Integer>(); + + for (Element element : model.getElements()) { + if (element instanceof Species) { + for (MiriamData md : ((Species) element).getMiriamData()) { + if (MiriamType.PUBMED.equals(md.getDataType())) { + try { + pubmedIds.add(Integer.parseInt(md.getResource())); + } catch (NumberFormatException e) { + logger.error("Problem with parsing: " + e.getMessage(), e); + } + } + } + } + } + for (Reaction reaction : model.getReactions()) { + for (MiriamData md : reaction.getMiriamData()) { + if (MiriamType.PUBMED.equals(md.getDataType())) { + try { + pubmedIds.add(Integer.parseInt(md.getResource())); + } catch (NumberFormatException e) { + logger.error("Problem with parsing: " + e.getMessage(), e); + } + } + } + } + double amount = pubmedIds.size(); + double counter = 0; + for (Integer id : pubmedIds) { + try { + Article art = backend.getPubmedArticleById(id); + if (art == null) { + logger.warn("Cannot find pubmed article. Pubmed_id = " + id); + } + } catch (PubmedSearchException e) { + logger.warn("Problem with accessing info about pubmed: " + id, e); + } + counter++; + updater.setProgress(IProgressUpdater.MAX_PROGRESS * counter / amount); + } + } + logger.debug("Caching finished"); + } + + @Override + public void updateModel(ModelData model, ProjectView selectedProject) { + + for (Model cachedModel : models.values()) { + if (cachedModel.getId().equals(selectedProject.getModelId())) { + setModel(cachedModel.getModelData(), selectedProject); + } + } + setModel(model, selectedProject); + modelDao.update(model); + } + + /** + * Sets the data from selectedProject into model. + * + * @param model + * destination of the data + * @param selectedProject + * source of the data + */ + private void setModel(ModelData model, ProjectView selectedProject) { + model.setNotes(selectedProject.getDescription()); + model.setMapVersion(selectedProject.getVersion()); + model.setNotifyEmail(selectedProject.getNotifyEmail()); + List<Layout> toRemove = new ArrayList<Layout>(); + for (Layout layout : model.getLayouts()) { + boolean exists = false; + for (LayoutView row : selectedProject.getLayouts()) { + if (layout.getId() == row.getIdObject()) { + exists = true; + // don't allow client side to edit layouts + // layout.setDirectory(row.getDirectory()); + layout.setTitle(row.getName()); + layout.setDescription(row.getDescription()); + } + } + if (!exists) { + toRemove.add(layout); + } + } + model.getLayouts().removeAll(toRemove); + + MiriamData disease = null; + if (selectedProject.getNewDiseaseName() != null) { + disease = new MiriamData(MiriamType.MESH_2012, selectedProject.getNewDiseaseName()); + } + + try { + if (meshParser.isValidMeshId(disease)) { + model.getProject().setDisease(disease); + } else { + model.getProject().setDisease(null); + selectedProject.setNewDiseaseName(null); + } + } catch (AnnotatorException e) { + logger.warn("Problem with accessing mesh db"); + } + + if (model.getProject() != null) { + MiriamData organism = null; + if (selectedProject.getNewOrganismName() != null && !selectedProject.getNewOrganismName().isEmpty()) { + organism = new MiriamData(MiriamType.TAXONOMY, selectedProject.getNewOrganismName()); + } + + try { + if (taxonomyBackend.getNameForTaxonomy(organism) != null) { + model.getProject().setOrganism(organism); + } else { + model.getProject().setOrganism(null); + } + } catch (TaxonomySearchException e) { + logger.error("Problem with accessing taxonomy db", e); + model.getProject().setOrganism(null); + } + } + + } + + @Override + public void removeModelFromCache(Model model) { + models.remove(model.getProject().getProjectId()); + + } + + /** + * @return the modelDao + * @see #modelDao + */ + public ModelDao getModelDao() { + return modelDao; + } + + /** + * @param modelDao + * the modelDao to set + * @see #modelDao + */ + public void setModelDao(ModelDao modelDao) { + this.modelDao = modelDao; + } + + /** + * @return the backend + * @see #backend + */ + public PubmedParser getBackend() { + return backend; + } + + /** + * @param backend + * the backend to set + * @see #backend + */ + public void setBackend(PubmedParser backend) { + this.backend = backend; + } + + @Override + public void cacheAllMiriamLinks(Model model, IProgressUpdater updater) { + logger.debug("Caching miriam ids..."); + if (model != null) { + Set<MiriamData> pubmedIds = new HashSet<MiriamData>(); + + for (Element element : model.getElements()) { + pubmedIds.addAll(element.getMiriamData()); + } + for (Reaction reaction : model.getReactions()) { + pubmedIds.addAll(reaction.getMiriamData()); + } + double amount = pubmedIds.size(); + double counter = 0; + for (MiriamData md : pubmedIds) { + miriamConnector.getUrlString(md); + counter++; + updater.setProgress(IProgressUpdater.MAX_PROGRESS * counter / amount); + } + } + logger.debug("Caching finished"); + + } + + @Override + public ModelView getModelView(Model model, User user) { + ModelView result = modelViewFactory.create(model); + if (user != null) { + result.setCustomLayouts(layoutService.getCustomLayouts(model, user)); + for (ModelView view : result.getSubmodels()) { + view.setCustomLayouts(layoutService.getCustomLayouts(model.getSubmodelById(view.getIdObject()), user)); + } + } + return result; + } + + @Override + public void removeModelFromCache(ModelData model) { + models.remove(model.getProject().getProjectId()); + } + + /** + * @return the layoutService + * @see #layoutService + */ + public ILayoutService getLayoutService() { + return layoutService; + } + + /** + * @param layoutService + * the layoutService to set + * @see #layoutService + */ + public void setLayoutService(ILayoutService layoutService) { + this.layoutService = layoutService; + } + + @Override + public void removeModelFromCacheByProjectId(String projectId) { + models.remove(projectId); + } + + @Override + public List<LightAliasView> getLightAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { + LightAliasViewFactory lightAliasViewFactory = new LightAliasViewFactory(); + List<LightAliasView> result = lightAliasViewFactory.createList(getAliasesByIds(model, identifiers)); + return result; + } + + /** + * Returns list of {@link Alias aliases} for given identifiers. + * + * @param model + * model where aliases are located + * @param identifiers + * list of alias identifiers in a given submodel. Every {@link Pair} + * contains information about {@link Model#getId() model identifier} + * (in {@link Pair#left}) and + * {@link lcsb.mapviewer.model.map.layout.alias.Alias#getId() alias + * identifier} (in {@link Pair#right}). + * @return list of {@link Alias aliases} for given identifiers + */ + private List<Alias> getAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { + Map<Integer, Set<Integer>> identifiersForMap = new HashMap<>(); + for (Pair<Integer, Integer> pair : identifiers) { + Set<Integer> set = identifiersForMap.get(pair.getLeft()); + if (set == null) { + set = new HashSet<>(); + identifiersForMap.put(pair.getLeft(), set); + } + set.add(pair.getRight()); + } + + List<Alias> result = new ArrayList<>(); + List<Model> models = new ArrayList<>(); + models.add(model); + models.addAll(model.getSubmodels()); + for (Model model2 : models) { + Set<Integer> set = identifiersForMap.get(model2.getModelData().getId()); + if (set != null) { + for (Alias alias : model2.getAliases()) { + if (set.contains(alias.getId())) { + result.add(alias); + set.remove(alias.getId()); + } + if (set.size() == 0) { + break; + } + } + if (set.size() > 0) { + Integer aliasId = set.iterator().next(); + throw new InvalidArgumentException("Cannot find alias (id: " + aliasId + ") in a model (id: " + model2.getModelData().getId() + ")"); + } + identifiersForMap.remove(model2.getModelData().getId()); + } + } + if (identifiersForMap.keySet().size() > 0) { + Integer modelId = identifiersForMap.keySet().iterator().next(); + Integer aliasId = identifiersForMap.get(modelId).iterator().next(); + throw new InvalidArgumentException("Cannot find alias (id: " + aliasId + ") in a model (id: " + modelId + "). Model doesn't exist."); + } + return result; + } + + @Override + public List<LightReactionView> getLightReactionsByIds(Model model, List<Pair<Integer, Integer>> identifiers) { + + Map<Integer, Set<Integer>> identifiersForMap = new HashMap<>(); + for (Pair<Integer, Integer> pair : identifiers) { + Set<Integer> set = identifiersForMap.get(pair.getLeft()); + if (set == null) { + set = new HashSet<>(); + identifiersForMap.put(pair.getLeft(), set); + } + set.add(pair.getRight()); + } + + List<LightReactionView> result = new ArrayList<>(); + List<Model> models = new ArrayList<>(); + models.add(model); + models.addAll(model.getSubmodels()); + for (Model model2 : models) { + Set<Integer> set = identifiersForMap.get(model2.getModelData().getId()); + if (set != null) { + for (Reaction reaction : model2.getReactions()) { + if (set.contains(reaction.getId())) { + result.add(new LightReactionView(reaction)); + set.remove(reaction.getId()); + } + if (set.size() == 0) { + break; + } + } + if (set.size() > 0) { + Integer aliasId = set.iterator().next(); + throw new InvalidArgumentException("Cannot find reaction (id: " + aliasId + ") in a model (id: " + model2.getModelData().getId() + ")"); + } + identifiersForMap.remove(model2.getModelData().getId()); + } + } + if (identifiersForMap.keySet().size() > 0) { + Integer modelId = identifiersForMap.keySet().iterator().next(); + Integer aliasId = identifiersForMap.get(modelId).iterator().next(); + throw new InvalidArgumentException("Cannot find reaction (id: " + aliasId + ") in a model (id: " + modelId + "). Model doesn't exist."); + } + return result; + } + + @Override + public List<FullAliasView> getFullAliasesByIds(Model model, List<Pair<Integer, Integer>> identifiers) { + List<FullAliasView> result = fullAliasViewFactory.createList(getAliasesByIds(model, identifiers)); + return result; + } + +} diff --git a/service/src/main/java/lcsb/mapviewer/services/search/db/TargetViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/db/TargetViewFactory.java index 69953b6392e0d942780fd214d2704b723accfe38..617961809d3857368b379a4ed8f972b840a786a5 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/db/TargetViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/db/TargetViewFactory.java @@ -1,155 +1,158 @@ -package lcsb.mapviewer.services.search.db; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.gson.Gson; - -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.annotation.data.ArticleCitationComparator; -import lcsb.mapviewer.annotation.data.Target; -import lcsb.mapviewer.annotation.data.TargetType; -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.common.exception.NotImplementedException; -import lcsb.mapviewer.model.map.AnnotatedObject; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; -import lcsb.mapviewer.services.view.AbstractViewFactory; -import lcsb.mapviewer.services.view.AnnotationViewFactory; - -/** - * Factory class for {@link TargetView} class. - * - * @author Piotr Gawron - * - */ -public class TargetViewFactory extends AbstractViewFactory<Target, TargetView> { - - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(TargetViewFactory.class); - - /** - * Factory object for {@link lcsb.mapviewer.services.view.AnnotationView} - * elements. - */ - @Autowired - private AnnotationViewFactory annotationViewFactory; - - /** - * Service accessing - * <a href="http://europepmc.org/RestfulWebService">pubmed</a>. - */ - @Autowired - private PubmedParser pubmedParser; - - @Override - public TargetView create(Target target) { - return create(target, null); - } - - /** - * Creates {@link TargetView} element for given {@link Target} and places - * links on the parameter {@link Model}. - * - * @param target - * object for which {@link TargetView} is created - * @param model - * {@link Model} where links will be placed - * @return {@link TargetView} element for given {@link Target} - */ - public TargetView create(Target target, Model model) { - TargetView result = new TargetView(); - if (target == null) { - return result; - } - result.setName(target.getName()); - if (target.getType() == null) { - logger.warn("Unknown type of target: " + target.getName() + ", target name: " + target.getName()); - } else { - result.setType(target.getType().getCommonName()); - } - - if (target.getType() == TargetType.SINGLE_PROTEIN || target.getType() == TargetType.COMPLEX_PROTEIN || target.getType() == TargetType.PROTEIN_FAMILY) { - result.setVisible(true); - result.setSelectable(false); - } - - for (MiriamData md : target.getGenes()) { - GeneRow geneRow = new GeneRow(); - geneRow.setAnnotation(annotationViewFactory.create(md)); - if (model != null) { - Set<AnnotatedObject> list = new HashSet<>(); - list.addAll(model.getSpeciesByName(md.getResource())); - list.addAll(model.getElementsByAnnotation(md)); - - int countInTopModel = list.size(); - for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) { - list.addAll(submodel.getSubmodel().getModel().getSpeciesByName(md.getResource())); - list.addAll(submodel.getSubmodel().getModel().getElementsByAnnotation(md)); - } - int counter = list.size(); - geneRow.setSelectable(counter > 0); - - if (counter > 0) { - geneRow.setSelectable(true); - if (target.getType() == TargetType.SINGLE_PROTEIN || target.getType() == TargetType.PROTEIN_FAMILY) { - result.setSelectable(true); - } - if (countInTopModel < counter) { - result.setAvailableInSubmodel(true); - } - } - } - result.addProtein(geneRow); - } - - // this should be fixed - // if (target.getType() == TargetType.COMPLEX_PROTEIN) { - // - // if (complexToOverlayList(target, null).size() > 0) { - // row.setSelectable(true); - // } - // } - - if (target.getSource() != null) { - result.setAnnotation(annotationViewFactory.create(target.getSource())); - } - for (MiriamData md : target.getReferences()) { - if (md.getDataType().equals(MiriamType.PUBMED)) { - try { - Integer id = Integer.parseInt(md.getResource()); - Article reference = pubmedParser.getPubmedArticleById(id); - if (reference != null) { - result.addReference(reference); - } - } catch (NumberFormatException e) { - logger.warn("Invalid pubmed reference: " + md); - } - } else { - logger.warn("Unknown reference type: " + md); - } - } - Collections.sort(result.getReferences(), new ArticleCitationComparator()); - - return result; - - } - - @Override - public String createGson(TargetView object) { - return new Gson().toJson(object); - } - - @Override - public Target viewToObject(TargetView view) { - throw new NotImplementedException(); - } -} +package lcsb.mapviewer.services.search.db; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.gson.Gson; + +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.data.ArticleCitationComparator; +import lcsb.mapviewer.annotation.data.Target; +import lcsb.mapviewer.annotation.data.TargetType; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.annotation.services.PubmedSearchException; +import lcsb.mapviewer.common.exception.NotImplementedException; +import lcsb.mapviewer.model.map.AnnotatedObject; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; +import lcsb.mapviewer.services.view.AbstractViewFactory; +import lcsb.mapviewer.services.view.AnnotationViewFactory; + +/** + * Factory class for {@link TargetView} class. + * + * @author Piotr Gawron + * + */ +public class TargetViewFactory extends AbstractViewFactory<Target, TargetView> { + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(TargetViewFactory.class); + + /** + * Factory object for {@link lcsb.mapviewer.services.view.AnnotationView} + * elements. + */ + @Autowired + private AnnotationViewFactory annotationViewFactory; + + /** + * Service accessing + * <a href="http://europepmc.org/RestfulWebService">pubmed</a>. + */ + @Autowired + private PubmedParser pubmedParser; + + @Override + public TargetView create(Target target) { + return create(target, null); + } + + /** + * Creates {@link TargetView} element for given {@link Target} and places + * links on the parameter {@link Model}. + * + * @param target + * object for which {@link TargetView} is created + * @param model + * {@link Model} where links will be placed + * @return {@link TargetView} element for given {@link Target} + */ + public TargetView create(Target target, Model model) { + TargetView result = new TargetView(); + if (target == null) { + return result; + } + result.setName(target.getName()); + if (target.getType() == null) { + logger.warn("Unknown type of target: " + target.getName() + ", target name: " + target.getName()); + } else { + result.setType(target.getType().getCommonName()); + } + + if (target.getType() == TargetType.SINGLE_PROTEIN || target.getType() == TargetType.COMPLEX_PROTEIN || target.getType() == TargetType.PROTEIN_FAMILY) { + result.setVisible(true); + result.setSelectable(false); + } + + for (MiriamData md : target.getGenes()) { + GeneRow geneRow = new GeneRow(); + geneRow.setAnnotation(annotationViewFactory.create(md)); + if (model != null) { + Set<AnnotatedObject> list = new HashSet<>(); + list.addAll(model.getSpeciesByName(md.getResource())); + list.addAll(model.getElementsByAnnotation(md)); + + int countInTopModel = list.size(); + for (ModelSubmodelConnection submodel : model.getSubmodelConnections()) { + list.addAll(submodel.getSubmodel().getModel().getSpeciesByName(md.getResource())); + list.addAll(submodel.getSubmodel().getModel().getElementsByAnnotation(md)); + } + int counter = list.size(); + geneRow.setSelectable(counter > 0); + + if (counter > 0) { + geneRow.setSelectable(true); + if (target.getType() == TargetType.SINGLE_PROTEIN || target.getType() == TargetType.PROTEIN_FAMILY) { + result.setSelectable(true); + } + if (countInTopModel < counter) { + result.setAvailableInSubmodel(true); + } + } + } + result.addProtein(geneRow); + } + + // this should be fixed + // if (target.getType() == TargetType.COMPLEX_PROTEIN) { + // + // if (complexToOverlayList(target, null).size() > 0) { + // row.setSelectable(true); + // } + // } + + if (target.getSource() != null) { + result.setAnnotation(annotationViewFactory.create(target.getSource())); + } + for (MiriamData md : target.getReferences()) { + if (md.getDataType().equals(MiriamType.PUBMED)) { + try { + Integer id = Integer.parseInt(md.getResource()); + Article reference = pubmedParser.getPubmedArticleById(id); + if (reference != null) { + result.addReference(reference); + } + } catch (NumberFormatException e) { + logger.warn("Invalid pubmed reference: " + md); + } catch (PubmedSearchException e) { + logger.warn("Problem with accessing info about pubmed: " + md, e); + } + } else { + logger.warn("Unknown reference type: " + md); + } + } + Collections.sort(result.getReferences(), new ArticleCitationComparator()); + + return result; + + } + + @Override + public String createGson(TargetView object) { + return new Gson().toJson(object); + } + + @Override + public Target viewToObject(TargetView view) { + throw new NotImplementedException(); + } +} diff --git a/service/src/main/java/lcsb/mapviewer/services/search/db/chemical/ChemicalViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/db/chemical/ChemicalViewFactory.java index 107a22c1e3dd155b673a77c5e2df0c9061c9f9b1..69f2559cdddcfd0c94ee3758c656c1d0ba0c4ec7 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/db/chemical/ChemicalViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/db/chemical/ChemicalViewFactory.java @@ -1,188 +1,193 @@ -package lcsb.mapviewer.services.search.db.chemical; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.gson.Gson; - -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.annotation.data.ArticleCitationComparator; -import lcsb.mapviewer.annotation.data.Chemical; -import lcsb.mapviewer.annotation.data.MeSH; -import lcsb.mapviewer.annotation.data.Target; -import lcsb.mapviewer.annotation.services.MeSHParser; -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; -import lcsb.mapviewer.model.map.Element; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.layout.alias.Alias; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.services.overlay.IconManager; -import lcsb.mapviewer.services.overlay.IconType; -import lcsb.mapviewer.services.search.SearchResultFactory; -import lcsb.mapviewer.services.search.data.ElementIdentifier; -import lcsb.mapviewer.services.search.db.DrugTargetViewVisibilityComparator; -import lcsb.mapviewer.services.search.db.TargetView; -import lcsb.mapviewer.services.search.db.TargetViewFactory; -import lcsb.mapviewer.services.view.AnnotationViewFactory; - -/** - * Factory class for {@link ChemicalView} class. - * - * @author Ayan Rota - * - */ -public class ChemicalViewFactory extends SearchResultFactory<Chemical, ChemicalView> { - - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(ChemicalViewFactory.class); - - /** - * Factory object used for creation of - * {@link lcsb.mapviewer.services.view.AnnotationView} elements. - */ - @Autowired - private AnnotationViewFactory annotationViewFactory; - - /** - * Service accessing - * <a href="http://europepmc.org/RestfulWebService">pubmed</a>. - */ - @Autowired - private PubmedParser pubmedParser; - - /** - * Factory object used for creation of {@link TargetView} elements. - */ - @Autowired - private TargetViewFactory drugTargetViewFactory; - - /** - * Service accessing <a href="http://europepmc.org/RestfulWebService">mesh</a> - * . - */ - @Autowired - private MeSHParser meSHParser; - - @Override - public ChemicalView create(Chemical chemical) { - return create(chemical, null, 0); - } - - /** - * Creates {@link ChemicalView}. - * - * @param chemical - * original Chemical from which the data will be initialized - * @param model - * model where the view will be presented - * @param set - * which set of icons should be used - * - * @return {@link ChemicalView} object for given chemical. links are placed - * according to model given in the parameter. - */ - public ChemicalView create(Chemical chemical, Model model, int set) { - ChemicalView chemicalView = new ChemicalView(chemical); - if (chemical == null) { - return chemicalView; - } - - chemicalView.setName(chemical.getChemicalName()); - if (chemical.getDirectEvidence() != null) { - chemicalView.setDirectEvedince(chemical.getDirectEvidence().getValue()); - } - - if (chemical.getChemicalId() != null) { - chemicalView.setSourceLink(annotationViewFactory.create(chemical.getChemicalId())); - try { - MeSH mesh = meSHParser.getMeSH(chemical.getChemicalId()); - if (mesh != null) { - chemicalView.setDescription(mesh.getDescription()); - chemicalView.setSynonyms(mesh.getSynonymsString()); - } else { - chemicalView.setDescription("Mesh term not available"); - chemicalView.setSynonyms("N/A"); - } - } catch (AnnotatorException e) { - logger.error("Problem with accessing mesh database", e); - chemicalView.setDescription("Mesh term not available"); - chemicalView.setSynonyms("N/A"); - } - } - - if (chemical.getCasID() != null) { - chemicalView.setCasLink(annotationViewFactory.create(chemical.getCasID())); - } - - List<Article> articles = new ArrayList<Article>(); - for (MiriamData publication : chemical.getDirectEvidencePublication()) { - if (publication.getDataType().equals(MiriamType.PUBMED)) { - Integer id = Integer.parseInt(publication.getResource()); - Article article = pubmedParser.getPubmedArticleById(id); - if (article != null) { - articles.add(article); - } - } else { - logger.warn("Unknown publication type: " + publication); - } - } - Collections.sort(articles, new ArticleCitationComparator()); - chemicalView.setDirectEvidencePubs(articles); - - List<TargetView> targetsRows = new ArrayList<>(); - - int differentNames = 0; - for (Target geneEntry : chemical.getInferenceNetwork()) { - targetsRows.add(drugTargetViewFactory.create(geneEntry, model)); - } - - Collections.sort(targetsRows, new DrugTargetViewVisibilityComparator()); - - for (TargetView geneTargetView : targetsRows) { - if (geneTargetView.getSelectable()) { - String icon = IconManager.getInstance().getIconForIndex(differentNames++, IconType.CHEMICAL, set); - geneTargetView.setIcon(icon); - geneTargetView.setSelected(true); - } - } - chemicalView.setTargetRows(targetsRows); - return chemicalView; - - } - - @Override - public String createGson(ChemicalView object) { - return new Gson().toJson(object); - } - - @Override - public List<ElementIdentifier> searchResultToElementIdentifier(ChemicalView chemical, Model inputModel) { - List<ElementIdentifier> result = new ArrayList<>(); - - List<Model> models = new ArrayList<>(); - models.addAll(inputModel.getSubmodels()); - models.add(inputModel); - for (Model model : models) { - for (TargetView target : chemical.getTargetRows()) { - if (target.getSelected() && target.getIcon() != null) { - for (Element element : model.getElements()) { - if (elementMatch(target, element)) { - for (Alias alias : model.getAliasesForElement(element)) { - result.add(new ElementIdentifier(alias, target.getIcon())); - } - } - } - } - } - } - return result; - } -} +package lcsb.mapviewer.services.search.db.chemical; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.gson.Gson; + +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.data.ArticleCitationComparator; +import lcsb.mapviewer.annotation.data.Chemical; +import lcsb.mapviewer.annotation.data.MeSH; +import lcsb.mapviewer.annotation.data.Target; +import lcsb.mapviewer.annotation.services.MeSHParser; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.annotation.services.PubmedSearchException; +import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; +import lcsb.mapviewer.model.map.Element; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.layout.alias.Alias; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.services.overlay.IconManager; +import lcsb.mapviewer.services.overlay.IconType; +import lcsb.mapviewer.services.search.SearchResultFactory; +import lcsb.mapviewer.services.search.data.ElementIdentifier; +import lcsb.mapviewer.services.search.db.DrugTargetViewVisibilityComparator; +import lcsb.mapviewer.services.search.db.TargetView; +import lcsb.mapviewer.services.search.db.TargetViewFactory; +import lcsb.mapviewer.services.view.AnnotationViewFactory; + +/** + * Factory class for {@link ChemicalView} class. + * + * @author Ayan Rota + * + */ +public class ChemicalViewFactory extends SearchResultFactory<Chemical, ChemicalView> { + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(ChemicalViewFactory.class); + + /** + * Factory object used for creation of + * {@link lcsb.mapviewer.services.view.AnnotationView} elements. + */ + @Autowired + private AnnotationViewFactory annotationViewFactory; + + /** + * Service accessing + * <a href="http://europepmc.org/RestfulWebService">pubmed</a>. + */ + @Autowired + private PubmedParser pubmedParser; + + /** + * Factory object used for creation of {@link TargetView} elements. + */ + @Autowired + private TargetViewFactory drugTargetViewFactory; + + /** + * Service accessing <a href="http://europepmc.org/RestfulWebService">mesh</a> + * . + */ + @Autowired + private MeSHParser meSHParser; + + @Override + public ChemicalView create(Chemical chemical) { + return create(chemical, null, 0); + } + + /** + * Creates {@link ChemicalView}. + * + * @param chemical + * original Chemical from which the data will be initialized + * @param model + * model where the view will be presented + * @param set + * which set of icons should be used + * + * @return {@link ChemicalView} object for given chemical. links are placed + * according to model given in the parameter. + */ + public ChemicalView create(Chemical chemical, Model model, int set) { + ChemicalView chemicalView = new ChemicalView(chemical); + if (chemical == null) { + return chemicalView; + } + + chemicalView.setName(chemical.getChemicalName()); + if (chemical.getDirectEvidence() != null) { + chemicalView.setDirectEvedince(chemical.getDirectEvidence().getValue()); + } + + if (chemical.getChemicalId() != null) { + chemicalView.setSourceLink(annotationViewFactory.create(chemical.getChemicalId())); + try { + MeSH mesh = meSHParser.getMeSH(chemical.getChemicalId()); + if (mesh != null) { + chemicalView.setDescription(mesh.getDescription()); + chemicalView.setSynonyms(mesh.getSynonymsString()); + } else { + chemicalView.setDescription("Mesh term not available"); + chemicalView.setSynonyms("N/A"); + } + } catch (AnnotatorException e) { + logger.error("Problem with accessing mesh database", e); + chemicalView.setDescription("Mesh term not available"); + chemicalView.setSynonyms("N/A"); + } + } + + if (chemical.getCasID() != null) { + chemicalView.setCasLink(annotationViewFactory.create(chemical.getCasID())); + } + + List<Article> articles = new ArrayList<Article>(); + for (MiriamData publication : chemical.getDirectEvidencePublication()) { + if (publication.getDataType().equals(MiriamType.PUBMED)) { + Integer id = Integer.parseInt(publication.getResource()); + try { + Article article = pubmedParser.getPubmedArticleById(id); + if (article != null) { + articles.add(article); + } + } catch (PubmedSearchException e) { + logger.error("Problem with accessing info about pubmed", e); + } + } else { + logger.warn("Unknown publication type: " + publication); + } + } + Collections.sort(articles, new ArticleCitationComparator()); + chemicalView.setDirectEvidencePubs(articles); + + List<TargetView> targetsRows = new ArrayList<>(); + + int differentNames = 0; + for (Target geneEntry : chemical.getInferenceNetwork()) { + targetsRows.add(drugTargetViewFactory.create(geneEntry, model)); + } + + Collections.sort(targetsRows, new DrugTargetViewVisibilityComparator()); + + for (TargetView geneTargetView : targetsRows) { + if (geneTargetView.getSelectable()) { + String icon = IconManager.getInstance().getIconForIndex(differentNames++, IconType.CHEMICAL, set); + geneTargetView.setIcon(icon); + geneTargetView.setSelected(true); + } + } + chemicalView.setTargetRows(targetsRows); + return chemicalView; + + } + + @Override + public String createGson(ChemicalView object) { + return new Gson().toJson(object); + } + + @Override + public List<ElementIdentifier> searchResultToElementIdentifier(ChemicalView chemical, Model inputModel) { + List<ElementIdentifier> result = new ArrayList<>(); + + List<Model> models = new ArrayList<>(); + models.addAll(inputModel.getSubmodels()); + models.add(inputModel); + for (Model model : models) { + for (TargetView target : chemical.getTargetRows()) { + if (target.getSelected() && target.getIcon() != null) { + for (Element element : model.getElements()) { + if (elementMatch(target, element)) { + for (Alias alias : model.getAliasesForElement(element)) { + result.add(new ElementIdentifier(alias, target.getIcon())); + } + } + } + } + } + } + return result; + } +} diff --git a/service/src/main/java/lcsb/mapviewer/services/view/AnnotationViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/view/AnnotationViewFactory.java index 39f49c3ac250e632c8a76f1f717e32fd08fbdfbb..c0a20024454f6626eaedeb748177b0c6097d5cf1 100644 --- a/service/src/main/java/lcsb/mapviewer/services/view/AnnotationViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/view/AnnotationViewFactory.java @@ -1,102 +1,108 @@ -package lcsb.mapviewer.services.view; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.gson.Gson; - -import lcsb.mapviewer.annotation.data.Article; -import lcsb.mapviewer.annotation.services.MiriamConnector; -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.graph.DataMiningType; - -/** - * Factory class for {@link AnnotationView} class. - * - * @author Piotr Gawron - * - */ -public class AnnotationViewFactory extends AbstractViewFactory<MiriamData, AnnotationView> { - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(AnnotationViewFactory.class); - - /** - * Local backend to the pubmed data. - */ - @Autowired - private PubmedParser pubmedParser; - - /** - * Local backend to the miriam registry. - */ - @Autowired - private MiriamConnector miriamConnector; - - @Override - public AnnotationView create(MiriamData object) { - AnnotationView result = new AnnotationView(object); - if (object != null && object.getDataType() != null) { - if (object.getDataType().getUris().size() > 0) { - try { - result.setLink(miriamConnector.getUrlString(object)); - } catch (Exception e) { - logger.error("Problem with miriam: " + object, e); - } - } - if (MiriamType.PUBMED.equals(object.getDataType())) { - String summary = pubmedParser.getSummary(object.getResource()); - // workaround, - // tak a look at Bug #461 - if (summary != null) { - result.setSummary(summary.replace("\\", "\\\\")); - } - } - result.setType(object.getDataType().getCommonName()); - result.setName(object.getResource()); - } - return result; - } - - /** - * Creates {@link AnnotationView} for {@link DataMiningType} object. - * - * @param dataMiningType - * type of datamining element - * @return {@link AnnotationView} for {@link DataMiningType} object - */ - public AnnotationView create(DataMiningType dataMiningType) { - AnnotationView result = new AnnotationView(null); - result.setName(dataMiningType.getCommonName()); - if (dataMiningType.getSource() != null) { - result.setLink(DataMiningType.STRUCTURE_ANALYSIS.getSource()); - } - return result; - } - - @Override - public String createGson(AnnotationView object) { - return new Gson().toJson(object); - } - - @Override - public MiriamData viewToObject(AnnotationView view) { - MiriamType type = MiriamType.getTypeByCommonName(view.getType()); - return new MiriamData(type, view.getName()); - } - - /** - * Creates {@link AnnotationView} from an {@link Article}. - * - * @param article - * object from which we create {@link AnnotationView} - * @return {@link AnnotationView} from an {@link Article} - */ - public AnnotationView create(Article article) { - return create(new MiriamData(MiriamType.PUBMED, article.getId())); - } - -} +package lcsb.mapviewer.services.view; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.gson.Gson; + +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.services.MiriamConnector; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.annotation.services.PubmedSearchException; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.graph.DataMiningType; + +/** + * Factory class for {@link AnnotationView} class. + * + * @author Piotr Gawron + * + */ +public class AnnotationViewFactory extends AbstractViewFactory<MiriamData, AnnotationView> { + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(AnnotationViewFactory.class); + + /** + * Local backend to the pubmed data. + */ + @Autowired + private PubmedParser pubmedParser; + + /** + * Local backend to the miriam registry. + */ + @Autowired + private MiriamConnector miriamConnector; + + @Override + public AnnotationView create(MiriamData object) { + AnnotationView result = new AnnotationView(object); + if (object != null && object.getDataType() != null) { + if (object.getDataType().getUris().size() > 0) { + try { + result.setLink(miriamConnector.getUrlString(object)); + } catch (Exception e) { + logger.error("Problem with miriam: " + object, e); + } + } + if (MiriamType.PUBMED.equals(object.getDataType())) { + try { + String summary = pubmedParser.getSummary(object.getResource()); + // workaround, + // tak a look at Bug #461 + if (summary != null) { + result.setSummary(summary.replace("\\", "\\\\")); + } + } catch (PubmedSearchException e) { + logger.error("Problem with accessing info about pubmed", e); + result.setSummary("N/A"); + } + } + result.setType(object.getDataType().getCommonName()); + result.setName(object.getResource()); + } + return result; + } + + /** + * Creates {@link AnnotationView} for {@link DataMiningType} object. + * + * @param dataMiningType + * type of datamining element + * @return {@link AnnotationView} for {@link DataMiningType} object + */ + public AnnotationView create(DataMiningType dataMiningType) { + AnnotationView result = new AnnotationView(null); + result.setName(dataMiningType.getCommonName()); + if (dataMiningType.getSource() != null) { + result.setLink(DataMiningType.STRUCTURE_ANALYSIS.getSource()); + } + return result; + } + + @Override + public String createGson(AnnotationView object) { + return new Gson().toJson(object); + } + + @Override + public MiriamData viewToObject(AnnotationView view) { + MiriamType type = MiriamType.getTypeByCommonName(view.getType()); + return new MiriamData(type, view.getName()); + } + + /** + * Creates {@link AnnotationView} from an {@link Article}. + * + * @param article + * object from which we create {@link AnnotationView} + * @return {@link AnnotationView} from an {@link Article} + */ + public AnnotationView create(Article article) { + return create(new MiriamData(MiriamType.PUBMED, article.getId())); + } + +} diff --git a/service/src/main/java/lcsb/mapviewer/services/view/PubmedAnnotatedElementsViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/view/PubmedAnnotatedElementsViewFactory.java index 20663ff1bf763ab9a9f845388df7a2e63ff6ece8..54dc5b2e7b5a03891c2d3a24c47165108c220341 100644 --- a/service/src/main/java/lcsb/mapviewer/services/view/PubmedAnnotatedElementsViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/view/PubmedAnnotatedElementsViewFactory.java @@ -1,79 +1,88 @@ -package lcsb.mapviewer.services.view; - -import java.util.Set; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; - -import com.google.gson.Gson; - -import lcsb.mapviewer.annotation.services.PubmedParser; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.common.exception.NotImplementedException; -import lcsb.mapviewer.model.map.AnnotatedObject; -import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.MiriamType; -import lcsb.mapviewer.model.map.model.Model; - -/** - * Factory class for {@link LayoutView} class. - * - * @author Piotr Gawron - * - */ -public class PubmedAnnotatedElementsViewFactory extends AbstractViewFactory<MiriamData, PubmedAnnotatedElementsView> { - /** - * Default class logger. - */ - @SuppressWarnings("unused") - private static Logger logger = Logger.getLogger(PubmedAnnotatedElementsViewFactory.class); - - /** - * Local backend to the pubmed data. - */ - @Autowired - private PubmedParser pubmedParser; - - @Override - public PubmedAnnotatedElementsView create(MiriamData element) { - PubmedAnnotatedElementsView result = new PubmedAnnotatedElementsView(element); - if (element == null) { - return result; - } else if (!MiriamType.PUBMED.equals(element.getDataType())) { - throw new InvalidArgumentException("Only " + MiriamType.PUBMED + " types are valid"); - } - result.setArticle(pubmedParser.getPubmedArticleById(Integer.valueOf(element.getResource()))); - return result; - } - - /** - * Creates publication summary for a given model. - * - * @param miriamData - * {@link MiriamData} representing article - * @param model - * model for which summary will be prepared - * @return publication summary for a given model and publication - */ - public PubmedAnnotatedElementsView create(MiriamData miriamData, Model model) { - PubmedAnnotatedElementsView result = create(miriamData); - Set<AnnotatedObject> elements = model.getElementsByAnnotation(miriamData); - for (Model submodel : model.getSubmodels()) { - elements.addAll(submodel.getElementsByAnnotation(miriamData)); - } - for (AnnotatedObject annotatedObject : elements) { - result.addElement(annotatedObject); - } - return result; - } - - @Override - public String createGson(PubmedAnnotatedElementsView object) { - return new Gson().toJson(object); - } - - @Override - public MiriamData viewToObject(PubmedAnnotatedElementsView view) { - throw new NotImplementedException(); - } -} +package lcsb.mapviewer.services.view; + +import java.util.Set; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.gson.Gson; + +import lcsb.mapviewer.annotation.data.Article; +import lcsb.mapviewer.annotation.services.PubmedParser; +import lcsb.mapviewer.annotation.services.PubmedSearchException; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.exception.NotImplementedException; +import lcsb.mapviewer.model.map.AnnotatedObject; +import lcsb.mapviewer.model.map.MiriamData; +import lcsb.mapviewer.model.map.MiriamType; +import lcsb.mapviewer.model.map.model.Model; + +/** + * Factory class for {@link LayoutView} class. + * + * @author Piotr Gawron + * + */ +public class PubmedAnnotatedElementsViewFactory extends AbstractViewFactory<MiriamData, PubmedAnnotatedElementsView> { + + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(PubmedAnnotatedElementsViewFactory.class); + + /** + * Local backend to the pubmed data. + */ + @Autowired + private PubmedParser pubmedParser; + + @Override + public PubmedAnnotatedElementsView create(MiriamData element) { + PubmedAnnotatedElementsView result = new PubmedAnnotatedElementsView(element); + if (element == null) { + return result; + } else if (!MiriamType.PUBMED.equals(element.getDataType())) { + throw new InvalidArgumentException("Only " + MiriamType.PUBMED + " types are valid"); + } + try { + result.setArticle(pubmedParser.getPubmedArticleById(Integer.valueOf(element.getResource()))); + } catch (PubmedSearchException e) { + Article article = new Article(); + article.setTitle("N/A"); + result.setArticle(article); + logger.error(e, e); + } + return result; + } + + /** + * Creates publication summary for a given model. + * + * @param miriamData + * {@link MiriamData} representing article + * @param model + * model for which summary will be prepared + * @return publication summary for a given model and publication + */ + public PubmedAnnotatedElementsView create(MiriamData miriamData, Model model) { + PubmedAnnotatedElementsView result = create(miriamData); + Set<AnnotatedObject> elements = model.getElementsByAnnotation(miriamData); + for (Model submodel : model.getSubmodels()) { + elements.addAll(submodel.getElementsByAnnotation(miriamData)); + } + for (AnnotatedObject annotatedObject : elements) { + result.addElement(annotatedObject); + } + return result; + } + + @Override + public String createGson(PubmedAnnotatedElementsView object) { + return new Gson().toJson(object); + } + + @Override + public MiriamData viewToObject(PubmedAnnotatedElementsView view) { + throw new NotImplementedException(); + } +}