package compbio.controllers; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import compbio.beans.ProteinBean; import compbio.beans.TotalByCounterBean; import compbio.cassandra.readers.ReaderByCounter; import compbio.cassandra.readers.SequenceReader; /** * Spring controller for supporting sequence queries. This version works in the * servlet style. * * @author Alexander Sherstnev * @author Natasha Sherstneva * * @since 0.5 * @version 1.0 December 2013 */ @Controller @RequestMapping("/sequence") public class SequenceController extends BasicController { /** * pattern for NON-protein alphabet symbols */ private final Pattern NONPROTEIN = Pattern.compile("[^ARNDCQEGHILKMFPSTWYV]+", Pattern.CASE_INSENSITIVE); /** * form a query page for search protein sequence. The servlet should be * available for users and admins only. * * @param model * MVC model * @return link to the JSP query page */ @RequestMapping(value = "query", method = RequestMethod.GET) public String formSequenceQuery(Map model) { model.put("username", getPrincipalName()); model.put("value", "AAAAA"); return "query/Sequence"; } /** * form a query page for statistics: Protein by job count. The servlet * should be available for users and admins only. * * @param model * MVC model * @return link to the JSP query page */ @RequestMapping(value = "counts/query", method = RequestMethod.GET) public String formCounterQuery(Map model) { model.put("username", getPrincipalName()); model.put("value", 5); return "query/SequenceCounts"; } /** * form a report page for search protein sequence. * * @param model * MVC model object * @param sequence * protein sequence or part of sequence * @param searchtype * defined whether the whole sequence or part of sequence would * be searched * @return link to the report JSP page */ @RequestMapping(value = "sequence/results", method = RequestMethod.GET) public String findSequence(@RequestParam("sequence") String sequence, @RequestParam("searchtype") String searchtype, Map model) { model.put("username", getPrincipalName()); final long startTime = System.currentTimeMillis(); // input checks String trimmedsequence = sequence.replaceAll("\\s", ""); if (trimmedsequence.equalsIgnoreCase("")) { model.put("error", "The sequence cann't be empty"); model.put("value", sequence); return "query/Sequence"; } if (NONPROTEIN.matcher(trimmedsequence).find()) { model.put("error", "The sequence contains symbols not from the standard protein alphabet"); model.put("value", sequence); return "query/Sequence"; } model.put("njobs", 0); model.put("prot", trimmedsequence); model.put("searchtype", searchtype); StringBuilder csvline = new StringBuilder(""); if (0 < trimmedsequence.length()) { SequenceReader reader = new SequenceReader(); List result = reader.readProteins(trimmedsequence, searchtype); model.put("results", result); if (null != result) { if (searchtype.equals("whole")) { model.put("njobs", result.get(0).getJobid().size()); } else { model.put("njobs", result.size()); } csvline.append("\'Job\',\'Annotation\',\'Sequence\'%0A"); for (ProteinBean entry : result) { List jobs = entry.getJobid(); String protein = entry.getSequence(); LinkedHashMap predictions = entry.getPredictions(); StringBuilder jobline = new StringBuilder(); for (Map.Entry pr : predictions.entrySet()) { jobline.append("\'\',\'" + pr.getKey() + "\',\'" + pr.getValue() + "\'%0A"); } for (String job : jobs) { csvline.append("\'" + job + "\',\'Sequence\',\'" + protein + "\',\'%0A" + jobline.toString()); } } } } model.put("csvfile", csvline.toString()); final long endTime = System.currentTimeMillis(); model.put("timeExecution", (endTime - startTime)); return "reports/Sequences"; } /** * form a report page for statistics: Protein by job count. * * @param model * MVC model object * @param counter * * @return link to the report JSP page */ @RequestMapping(value = "counts/results", method = RequestMethod.GET) public String countSequences(@RequestParam("counterJob") String counter, Map model) { model.put("username", getPrincipalName()); final long startTime = System.currentTimeMillis(); if (counter.equals("")) { model.put("error", "The value must not be empty"); model.put("value", counter); return "query/SequenceCounts"; } int realcounter; try { realcounter = Integer.parseInt(counter.trim()); } catch (NumberFormatException e) { model.put("error", "The value must be an integer number"); model.put("value", counter); return "query/SequenceCounts"; } if (realcounter < 1) { model.put("error", "The value must be greater than 0"); model.put("value", counter); return "query/SequenceCounts"; } ReaderByCounter reader = new ReaderByCounter(); List r = reader.readProteinByCounter(realcounter); model.put("results", r); model.put("njobs", 0); StringBuilder csvline = new StringBuilder(""); if (null != r) { model.put("njobs", r.size()); // form line for CSV file csvline.append("\'Job%20 count\', \'Protein%20Sequence\'%0A"); for (TotalByCounterBean b : r) { if (b.getName().equals("")) { // fix problem with records without protein sequence // (alignment jobs) csvline.append("\'" + b.getTotaljobs() + "\',\'Alignment%20job\'%0A"); b.setName("Alignment job"); } else { csvline.append("\'" + b.getTotaljobs() + "\',\'" + b.getName() + "\'%0A"); } } } model.put("csvfile", csvline.toString()); model.put("results", r); final long endTime = System.currentTimeMillis(); model.put("timeExecution", (endTime - startTime)); model.put("counter", realcounter); return "reports/SequencesStatistics"; } }