[Biojava-l] BLAST/Java interface

Ryan Golhar rgolhar@telocity.com
Thu, 22 Aug 2002 17:13:10 -0400


This is a multi-part message in MIME format.

------=_NextPart_000_001B_01C249FF.31365E50
Content-Type: text/plain;
	charset="US-ASCII"
Content-Transfer-Encoding: 7bit

Nathan,

Here's a class I wrote to BLAST sequences to NCBI and get results back as
XML.  This should give you a good start...If you have any questions, let me
know...



-----Original Message-----
From: biojava-l-admin@biojava.org [mailto:biojava-l-admin@biojava.org]On
Behalf Of nathan whitehouse
Sent: Thursday, August 22, 2002 4:39 PM
To: biojava-l@biojava.org
Subject: [Biojava-l] BLAST/Java interface


Hello people at BioJava,

  I'm modifying an existing Java applet-servlet used
by this lab.

  People want us to add BLAST to this applet.

  Anybody know of a good way to do this?

   Are there convenient BLAST libraries to call from
the servlet?  We've talked about calling a C or C++
library using the JNI.  I've looked around and it
seems that there's no modularized BLAST lying around
that would make this easy.
  The simple way to do it is just call BLASTAll from
the shell with its arguments.  But this is a hack; I
want to know if there is a better way to pass objects
in and out of BLAST.

  Thanks!
  Nathan

  Nathan Whitehouse
  Shaulsky Lab
  Baylor College of Medicine
  Houston, Texas, USA

__________________________________________________
Do You Yahoo!?
HotJobs - Search Thousands of New Jobs
http://www.hotjobs.com
_______________________________________________
Biojava-l mailing list  -  Biojava-l@biojava.org
http://biojava.org/mailman/listinfo/biojava-l

------=_NextPart_000_001B_01C249FF.31365E50
Content-Type: application/octet-stream;
	name="BLAST.java"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="BLAST.java"

package org.umdnj.JBLAST;

import java.net.*;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
/*
 * BLAST.java
 *
 * Created on May 20, 2002, 2:49 PM
 */

/**
 *
 * @author  Ryan Golhar (golharam@umdnj.edu)
 * @version
 */
public class BLAST {

    /** Creates new BLAST */
    public BLAST() {
    }

    // establish an HTTP connection with NCBI
    private boolean connectNCBI() {
        try {
            m_sock =3D new Socket(m_URL, 80);
            if (m_sock.isConnected() =3D=3D false) {
                System.err.println("Unable to connect to NCBI server");
                return false;
            } else {
                m_sock.setKeepAlive(true);

                m_out =3D new BufferedWriter(new =
OutputStreamWriter(m_sock.getOutputStream()));
                m_in =3D new BufferedReader(new =
InputStreamReader(m_sock.getInputStream()));
            }
        } catch (UnknownHostException e) {
            System.out.println("UnknownHostException occurred: " + =
e.getMessage());
            return false;
        }
        catch (SocketException e) {
            System.out.println("SocketException occurred: " + =
e.getMessage());
        }
        catch (IOException e) {
            System.out.println("IOException occurred: " + =
e.getMessage());
            return false;
        }

        return true;
    }

    private void disconnectNCBI() {
        try {
            m_out.close();
            m_in.close();
            m_sock.close();
        }
        catch (IOException e) {
            System.out.println("IOException occurred: " + =
e.getMessage());
        }
    }

    // find the =3D sign, then store the key and value
    private void storeKeyValue(String key, Object value) {
        m_retParms.put(key, value);
    }

    private boolean storeKeyValue(String keyvalue) {
		String key;
		String value;
		int iEqual =3D keyvalue.indexOf("=3D");

		if (iEqual =3D=3D -1)
		    return false;

		key =3D keyvalue.substring(0, iEqual);
		value =3D keyvalue.substring(iEqual+1, keyvalue.length());

        storeKeyValue(key.trim(), value.trim());

		return true;
    }

    private String getResponseFromNCBI() {
        String responseline;
        StringBuffer response =3D new StringBuffer();

        try {
            responseline =3D m_in.readLine();

            while (responseline !=3D null) {
                response.append(responseline + "\n");
                responseline =3D m_in.readLine();
            }
        } catch (IOException e) {
            System.out.println("Exception occurred in =
getResponseFromNCBI: " + e.getMessage());
        }

        return response.toString();
    }

    // this shouldn't be here, but for now until we figure out the =
problem
    // with the DTD's, we won't use a DOCTYPE in the XML results...
    // in is the entire XML doc, 2nd line should be DOCTYPE
    private String removeDocType(String in) {
        int i =3D in.indexOf("<!DOCTYPE");

        if (i =3D=3D -1) {
            System.out.println("DOCTYPE not found in XML Document");
            return in;
        }

        StringBuffer xml =3D new StringBuffer();

        xml.append(in.substring(0, i-1));

        // find the end of the DOCTYPE line
        i =3D in.indexOf(">", i);

        if (i =3D=3D -1) {
            System.out.println("DOCTYPE line closing not found in XML =
Document");
            return in;
        }

        xml.append(in.substring(i+1));
        return xml.toString();
    }

    private String parseForXML(String in) {
        int i =3D in.indexOf("<?xml");
        String xml =3D new String();

        if (i =3D=3D -1)
            return in;

        xml =3D in.substring(i);
        return removeDocType(xml);
    }

    // process messages from NCBI
/*  Look for:
    QBlastInfoBegin
	...
    QBlastInfoEnd
*/
    private void handleResponse() {
        int iStart, iEnd;
        String response =3D getResponseFromNCBI();

        if (m_retParms =3D=3D null)
            m_retParms =3D new HashMap(5);
        else
            m_retParms.clear();

        if ((iStart =3D response.indexOf("QBlastInfoBegin")) !=3D -1) {
            // parse as QBlastInfo
            iStart +=3D 17; // length of 'QBlastInfoBegin\r\n'
            iEnd =3D response.indexOf("QBlastInfoEnd");
            if ((iEnd <=3D iStart) || (iEnd =3D=3D -1)) {
                System.out.println("Error parsing QBlastInfo");
                return;
            }

            String strQBlastInfo =3D response.substring(iStart, iEnd);

            // find all the key-value pairs in the QBlastInfo section =
and store
            // storeKeyValue(response);
            StringTokenizer stk =3D new StringTokenizer(strQBlastInfo, =
"=3D\r\n", false);
            if ((stk.countTokens() % 2) !=3D 0) {
                System.out.println("Error: Incorrect number of tokens");
                System.out.println("Tokenized String:\n" + =
strQBlastInfo);
                System.out.println("Token count =3D " + =
stk.countTokens());
                return;
            }

            try {
                while (true) {
                    String key =3D stk.nextToken();
                    String value =3D stk.nextToken();
                    storeKeyValue(key.trim(), value.trim());
                }
            } catch (NoSuchElementException e) {
            }
        } else if (response.indexOf("<?xml") !=3D -1) {
            // parse as XML
            response =3D parseForXML(response);

            DocumentBuilderFactory dbf =3D =
DocumentBuilderFactory.newInstance();
            DocumentBuilder db =3D null;
            org.w3c.dom.Document doc =3D null;

            try {
                db =3D dbf.newDocumentBuilder();
            }
            catch (ParserConfigurationException e) {
                System.out.println("ParserConfigurationException =
occurred in handleResponse(): " + e.getMessage());
            }

            if (db !=3D null) {
                try {
                    // todo: This method of conversion is deprecated.  =
Must update this.
                    // Reader
                    StringBufferInputStream in =3D new =
StringBufferInputStream(response);

                    // InputStream
                    doc =3D db.parse(in, m_DTDDefinitions);
                }
                catch (org.xml.sax.SAXException e) {
                    System.out.println("SAXException occurred in =
handleResponse(): " + e.getMessage());
                    e.printStackTrace();
                }
                catch (IOException e) {
                    System.out.println("IOException occurred in =
handleResponse(): " + e.getMessage());
                    e.printStackTrace();
                }

                if (doc !=3D null) {
                    storeKeyValue("Status", "READY");
                    storeKeyValue("XML", doc);
                }
            }
        } else {
            System.out.println("Do not know how to process the =
response:");
            System.out.println(response);
        }
    }

    // urlencode str
    private String encode(String str) {
        String enc;

		// URL encode the parameters (in: req, out:enc)
		try {
            enc =3D URLEncoder.encode(str, "UTF-8");
		} catch (java.io.UnsupportedEncodingException e) {
		    enc =3D str;
		}
		return enc;
    }

    // construct the request packet to send to NCBI
    private String makeRequest(String cmd, String parms, String =
searchSeq) {
		String Request =3D null;
		StringBuffer DataPacket;

		DataPacket =3D new StringBuffer("\n\nCMD=3D" + cmd);

		if (parms !=3D null)
			DataPacket.append("&" + parms);

		if (searchSeq !=3D null) {
			DataPacket.append("&QUERY=3D");
			DataPacket.append(encode(searchSeq));
		}

		Request =3D m_strHeader + (DataPacket.length()-2) + DataPacket;

		return Request;
    }

    private void sendRequest(String request) {
        try {
            m_out.write(request);
            m_out.flush();
        } catch (IOException e) {
            System.out.println("IOException occurred: " + =
e.getMessage());
        }
    }

    // executes the Delete command
    public boolean exeDelete(java.lang.String rid) {
		String req =3D null;

        // 1. Connect to NCBI
        if (connectNCBI() !=3D true)
            return false;

        // 2. Send request
        req =3D makeRequest("Delete", "RID=3D"+rid, null);
        sendRequest(req);

        // 3. Get req id (handle the ret values)
		handleResponse();

        // 4. Get results
		disconnectNCBI();

        return true;
    }

    // executes the Get command
    public boolean exeGet(java.lang.String rid) {
		String req =3D null;

        // 1. Connect to NCBI
        if (connectNCBI() !=3D true) {
            System.out.println("Unable to connect to NCBI");
            return false;
        }

        // 2. Send request
        req =3D makeRequest("Get", "FORMAT_TYPE=3DXML&RID=3D"+rid, =
null);

        sendRequest(req);

        // 3. Get req id (handle the ret values)
		handleResponse();

        // 4. Get results
		disconnectNCBI();

        return true;
    }

    // executes the Put command for blastn
    public boolean exePut(java.lang.String seq) {
		String req =3D null;

        // 1. Connect to NCBI
        if (connectNCBI() !=3D true)
            return false;

        // 2. Send request
        req =3D makeRequest("Put", =
"PROGRAM=3Dblastn&DATABASE=3Dnr&HITLIST_SIZE=3D10", seq);

        sendRequest(req);

        // 3. Get req id (handle the ret values)
		handleResponse();
        m_retParms.put("Status", "Sent");

        // 4. Get results
		disconnectNCBI();

        return true;
    }

    // Execute the Info command
    public boolean exeInfo() {
		String req =3D null;

        // 1. Connect to NCBI
        if (connectNCBI() !=3D true)
            return false;

        // 2. Send request
        req =3D makeRequest("Info", null, null);

        sendRequest(req);

        // 3. Get req id (handle the ret values)
		handleResponse();

        // 4. Get results
		disconnectNCBI();

        return true;
    }

	public HashMap getReturnStatus() {
		return (HashMap)m_retParms.clone();
	}

    private BufferedReader m_in;
    private BufferedWriter m_out;
    private String m_URL =3D "www.ncbi.nlm.nih.gov";
    private String m_DTDDefinitions =3D =
"http://www.ncbi.nlm.nih.gov/dtd/";
    private Socket m_sock =3D null;
    private String m_strHeader =3D "POST /blast/Blast.cgi =
HTTP/1.0\nUser-Agent: JBlast\nConnection: Keep-Alive\nContent-type: =
application/x-www-form-urlencoded\nContent-Length: ";
    private HashMap m_retParms =3D null;
}

------=_NextPart_000_001B_01C249FF.31365E50--