/* * Copyright (c) 2006 Genome Research Limited. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2 of the License or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this program; see the file COPYING.LIB. If not, write to * the Free Software Foundation Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307 USA */ package org.genedb.web.mvc.controller; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.io.Writer; import java.util.Hashtable; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletResponse; import org.genedb.db.dao.SequenceDao; import org.gmod.schema.feature.Polypeptide; import org.gmod.schema.feature.ProductiveTranscript; import org.gmod.schema.feature.Transcript; import org.gmod.schema.mapped.Feature; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * Looks up a feature by unique name * * @author Chinmay Patel (cp2) * @author Adrian Tivey (art) * @author gv1 */ @Controller @RequestMapping("/SequenceDistributor") public class SequenceDistributorController { private static final Logger logger = Logger.getLogger(SequenceDistributorController.class); private static final String LOCAL_BLAST = "http://www.genedb.org/blast/submitblast"; private SequenceDao sequenceDao; @RequestMapping(method=RequestMethod.GET, value="/{name}/{type}/{destination}") public void process( HttpServletResponse response, @PathVariable(value="name") String uniqueName, @PathVariable(value="destination") String destination, @PathVariable(value="type") String sequenceType ) throws IOException { Writer writer = response.getWriter(); response.setContentType("text/html"); Feature feature = sequenceDao.getFeatureByUniqueName(uniqueName, Feature.class); if (feature == null) { writer.append(String.format("Failed to find feature '%s'", uniqueName)); //be.reject("no.results"); //return showForm(request, response, be); return; // FIXME } Transcript transcript = modelBuilder.findTranscriptForFeature(feature); String sequence = null; String sequence2 = null; boolean nucleotide = true; String program = "wublastn"; SequenceType st = SequenceType.valueOf(sequenceType); switch (st) { case GENE_SEQUENCE: sequence = transcript.getGene().getResidues(); sequence2 = getSequence(transcript, GeneSection.TRANSCRIPTIONAL_START, 0, GeneSection.POLY_A, 0, true, true); compareSequences(sequence, sequence2); break; case TRANSCRIPT: sequence = transcript.getResidues(); sequence2 = getSequence(transcript, GeneSection.TRANSCRIPTIONAL_START, 0, GeneSection.POLY_A, 0, true, false); compareSequences(sequence, sequence2); break; case CDS: sequence = transcript.getResidues(); sequence2 = getSequence(transcript, GeneSection.START_CODON, 0, GeneSection.STOP_CODON, 0, true, false); compareSequences(sequence, sequence2); break; case PROTEIN: if (transcript instanceof ProductiveTranscript) { Polypeptide pp = ((ProductiveTranscript) transcript).getProtein(); if (pp != null) { sequence = pp.getResidues(); if (sequence.endsWith("*")) { sequence = sequence.substring(0, sequence.length()-1); } nucleotide = false; } } program = "wublastx"; } String unsplitSequence = sequence; // sequence = splitSequenceIntoLines(sequence); SequenceDestination sd = SequenceDestination.valueOf(destination); switch (sd) { case BLAST: String uri = String.format("%s/%s", LOCAL_BLAST, "GeneDB_" + transcript.getOrganism().getCommonName() ); Map<String,String> parameters = new Hashtable<String,String>(); parameters.put("sequence", sequence); parameters.put("blast_type", program); writer.append( postForm(uri, parameters) ); break; // String returnable = String.format("redirect:%s/%s?sequence=%s&blast_type=%s", // LOCAL_BLAST, // "GeneDB_" + transcript.getOrganism().getCommonName(), // sequence, // program // ); // // // logger.error(returnable); // return returnable; case OMNIBLAST: String uri2 = String.format("%s/%s", LOCAL_BLAST, nucleotide ? "GeneDB_transcripts/omni" : "GeneDB_proteins/omni" ); Map<String,String> parameters2 = new Hashtable<String,String>(); parameters2.put("sequence", sequence); parameters2.put("blast_type", program); writer.append( postForm(uri2, parameters2)) ; break; // return String.format("redirect:%s/%s?sequence=%s&blast_type=%s", // LOCAL_BLAST, // nucleotide ? "GeneDB_transcripts/omni" : "GeneDB_proteins/omni", // sequence, // program // ); case NCBI_BLAST: String uri3 = "http://blast.ncbi.nlm.nih.gov/Blast.cgi"; Map<String,String> parameters3 = new Hashtable<String,String>(); parameters3.put("PAGE_TYPE", "BlastSearch"); parameters3.put("SHOW_DEFAULTS", "on"); parameters3.put("LINK_LOC", "blasthome"); if (nucleotide) { parameters3.put("PROGRAM", "blastn"); parameters3.put("BLAST_PROGRAMS", "megaBlast"); parameters3.put("DBTYPE", "gc"); parameters3.put("DATABASE", "nr"); } else { parameters3.put("PROGRAM", "blastp"); parameters3.put("BLAST_PROGRAMS", "blastp"); } parameters3.put("QUERY", unsplitSequence); writer.append( postForm(uri3, parameters3)); break; // return String.format("redirect:%s&%s&QUERY=%s", // "http://blast.ncbi.nlm.nih.gov/Blast.cgi?PAGE_TYPE=BlastSearch&SHOW_DEFAULTS=on&LINK_LOC=blasthome", // nucleotide ? // "PROGRAM=blastn&BLAST_PROGRAMS=megaBlast&DBTYPE=gc&DATABASE=nr" // : "PROGRAM=blastp&BLAST_PROGRAMS=blastp", // sequence // ); default: throw new RuntimeException("Unknown sequence destination"); } } private String postForm(String uri, Map<String,String> parameters) { StringBuilder sb = new StringBuilder(); sb.append(String.format("<html><title>redirect</title></html><body onLoad='doSubmit()'><form id='ncbi' action='%s' method='POST'>", uri)); for(Entry<String,String> entry : parameters.entrySet()) { sb.append(String.format("<input name='%s' value='%s' type='HIDDEN'>", entry.getKey(), entry.getValue())); } sb.append("<noscript>You appear to have Javascript disabled, please use the submit button: <input type='SUBMIT'></noscript>"); sb.append("</form>"); sb.append("<script> function doSubmit() { \n" + " document.forms['ncbi'].submit(); \n" + "} \n" + "</script>"); sb.append("</body>"); return sb.toString(); } private String post(String uri, Map<String,String> parameters) { final PostMethod postMethod = new PostMethod(uri); logger.debug(uri); for(Entry<String,String> entry : parameters.entrySet()) { // logger.error(entry.getKey()); // logger.error(entry.getValue()); postMethod.addParameter( entry.getKey(), entry.getValue()); } HttpClient client = new HttpClient(); int statusCode; try { statusCode = client.executeMethod( postMethod ); if( statusCode == HttpStatus.SC_OK ) { final InputStream responseBodyStream = postMethod.getResponseBodyAsStream(); StringWriter writer = new StringWriter(); IOUtils.copy(responseBodyStream, writer); responseBodyStream.close(); return writer.toString(); } } catch (HttpException e) { logger.error(e); e.printStackTrace(); } catch (IOException e) { logger.error(e); e.printStackTrace(); } return "Sorry but could not prepare the BLAST form. Please contact webmaster@genedb.org with information on the gene that caused this problem."; } private String getSequence(Transcript transcript, GeneSection start, int length1, GeneSection end, int length2, boolean exons, boolean introns) { Feature topLevelFeature = transcript.getPrimarySourceFeature(); int min = transcript.getFmin() - length1; min = (min < 0) ? 0 : min; int max = transcript.getFmax() + length2; max = (max < topLevelFeature.getSeqLen()) ? topLevelFeature.getSeqLen() : max; String seq = topLevelFeature.getResidues(min, max); return seq; } private void compareSequences(String sequence, String sequence2) { if (sequence.equals(sequence2)) { logger.error("Sequences match"); } else { logger.error("Sequences differ"); } } private int LINE_LENGTH = 40; private String splitSequenceIntoLines(String sequence) { StringBuilder ret = new StringBuilder(); String remaining = sequence; while (remaining.length() > LINE_LENGTH) { ret.append(remaining.substring(0, LINE_LENGTH)); ret.append("%0A"); remaining = remaining.substring(LINE_LENGTH); } if (remaining.length() != 0) { ret.append(remaining); } return ret.toString(); } public void setSequenceDao(SequenceDao sequenceDao) { this.sequenceDao = sequenceDao; } private ModelBuilder modelBuilder; public void setModelBuilder(ModelBuilder modelBuilder) { this.modelBuilder = modelBuilder; } }