Java tutorial
/* $Id: NCBIBlastClient.java 2459 2013-01-25 12:35:31Z hpm $ * ====================================================================== * * Copyright 2009-2013 EMBL - European Bioinformatics Institute * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ====================================================================== * JDispatcher NCBI BLAST (SOAP) web service Java client using Axis 1.x. * ---------------------------------------------------------------------- * Tested with: * Sun Java 1.5.0_17 with Apache Axis 1.4 on CentOS 5.2. * ====================================================================== */ package JavaFiles; import java.io.File; import java.io.IOException; import java.rmi.RemoteException; import javax.xml.rpc.Call; import javax.xml.rpc.ServiceException; import org.apache.axis.transport.http.HTTPConstants; import org.apache.commons.cli.*; import uk.ac.ebi.webservices.axis1.stubs.ncbiblast.*; /** * <p> * JDispatcher NCBI BLAST (SOAP) web service Java client using Apache Axis 1.x. * </p> * * <p> * See: * </p> * <ul> * <li><a * href="http://www.ebi.ac.uk/Tools/webservices/services/sss/ncbi_blast_soap" * >http://www.ebi.ac.uk/Tools/webservices/services/sss/ncbi_blast_soap</a></li> * <li><a * href="http://www.ebi.ac.uk/Tools/webservices/tutorials/06_programming/java" * >http://www.ebi.ac.uk/Tools/webservices/tutorials/06_programming/java</a></li> * <li><a href="http://ws.apache.org/axis/">http://ws.apache.org/axis/</a></li> * </ul> */ public class NCBIBlastClient extends AbstractWsToolClient { /** Proxy object for web service. */ private JDispatcherService_PortType srvProxy = null; /** Client version/revision for use in user-agent string. */ private String revision = "$Revision: 2459 $"; /** Tool specific usage for help. */ private static final String usageMsg = "NCBI BLAST\n" + "==========\n" + "\n" + "Rapid sequence database search programs utilizing the BLAST algorithm\n" + "\n" + "For more information see:\n" + "- http://www.ebi.ac.uk/Tools/sss/ncbiblast\n" + "- http://www.ebi.ac.uk/Tools/webservices/services/sss/ncbi_blast_soap\n" + "\n" + "[Required]\n" + "\n" + " -p, --program : str : BLAST program to use: see --paramDetail program\n" + " -D, --database : str : database(s) to search, space seperated: see\n" + " --paramDetail database\n" + " --stype : str : query sequence type\n" + " seqFile : file : query sequence (\"-\" for STDIN, @filename for \n" + " identifier list file)\n" + "\n" + "[Optional]\n" + "\n" + " -m, --matrix : str : scoring matrix, see --paramDetail matrix\n" + " -e, --exp : real : 0<E<= 1000. Statistical significance threshold\n" + " for reporting database sequence matches.\n" + " -f, --filter : : low complexity sequence filter, see\n" + " --paramDetail filter\n" + " -A, --align : int : alignment format, see --paramDetail align\n" + " -s, --scores : int : maximum number of scores to report\n" + " -n, --alignments : int : maximum number of alignments to report\n" + " -u, --match : int : score for a match (BLASTN only)\n" + " -v, --mismatch : int : score for a missmatch (BLASTN only)\n" + " -o, --gapopen : int : gap open penalty\n" + " -x, --gapext : int : gap extension penalty\n" + " -d, --dropoff : int : drop-off score\n" + " -g, --gapalign : : optimise gapped alignments\n" + " --seqrange : str : region in query sequence to use for search\n" + " --multifasta : : treat input as a set of fasta formatted sequences\n"; /** * Default constructor. */ public NCBIBlastClient() { // Set the HTTP user agent string for (java.net) requests. this.setUserAgent(); } /** <p>Get a user-agent string for this client.</p> * * <p><b>Note</b>: this affects all java.net based requests, but not the * Axis requests. The user-agent used by Axis is set from the * /org/apache/axis/i18n/resource.properties file included in the Axis * JAR.</p> * * @return Client user-agent string. */ protected String getClientUserAgentString() { printDebugMessage("getClientUserAgent", "Begin", 11); String clientVersion = this.revision.substring(11, this.revision.length() - 2); String clientUserAgent = "EBI-Sample-Client/" + clientVersion + " (" + this.getClass().getName() + "; " + System.getProperty("os.name") + ")"; printDebugMessage("getClientUserAgent", "End", 11); return clientUserAgent; } /** Print usage message. */ private static void printUsage() { System.out.println(usageMsg); printGenericOptsUsage(); } /** * Ensure that a service proxy is available to call the web service. * * @throws ServiceException */ protected void srvProxyConnect() throws ServiceException { printDebugMessage("srvProxyConnect", "Begin", 11); if (this.srvProxy == null) { JDispatcherService_Service service = new JDispatcherService_ServiceLocatorExtended(); if (this.getServiceEndPoint() != null) { try { this.srvProxy = service .getJDispatcherServiceHttpPort(new java.net.URL(this.getServiceEndPoint())); } catch (java.net.MalformedURLException ex) { System.err.println(ex.getMessage()); System.err.println("Warning: problem with specified endpoint URL. Default endpoint used."); this.srvProxy = service.getJDispatcherServiceHttpPort(); } } else { this.srvProxy = service.getJDispatcherServiceHttpPort(); } } printDebugMessage("srvProxyConnect", "End", 11); } /** Wrapper for JDispatcherService_ServiceLocator to enable HTTP * compression. * * Compression requires Commons HttpClient and a client-config.wsdd which * specifies that Commons HttpClient should be used as the HTTP transport. * See http://wiki.apache.org/ws/FrontPage/Axis/GzipCompression. */ private class JDispatcherService_ServiceLocatorExtended extends JDispatcherService_ServiceLocator { private static final long serialVersionUID = 1L; public Call createCall() throws ServiceException { Call call = super.createCall(); // Enable response compression. call.setProperty(HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE); // TEST: Enable request compression (requires service support) //call.setProperty(HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE); return call; } } /** * Get the web service proxy so it can be called directly. * * @return The web service proxy. * @throws javax.xml.rpc.ServiceException */ public JDispatcherService_PortType getSrvProxy() throws javax.xml.rpc.ServiceException { printDebugMessage("getSrvProxy", "", 1); this.srvProxyConnect(); // Ensure the service proxy exists return this.srvProxy; } /** * Get list of tool parameter names. * * @return String array containing list of parameter names * @throws ServiceException * @throws RemoteException */ public String[] getParams() throws ServiceException, RemoteException { printDebugMessage("getParams", "Begin", 1); String[] retVal = null; this.srvProxyConnect(); // Ensure the service proxy exists retVal = this.srvProxy.getParameters(); printDebugMessage("getParams", retVal.length + " params", 2); printDebugMessage("getParams", "End", 1); return retVal; } /** * Get detailed information about the specified tool parameter. * * @param paramName * Tool parameter name * @return Object describing tool parameter * @throws ServiceException * @throws RemoteException */ public WsParameterDetails getParamDetail(String paramName) throws ServiceException, RemoteException { printDebugMessage("getParamDetail", paramName, 1); this.srvProxyConnect(); // Ensure the service proxy exists return this.srvProxy.getParameterDetails(paramName); } /** * Print detailed information about a tool parameter. * * @param paramName * Name of the tool parameter to get information for. * @throws RemoteException * @throws ServiceException */ protected void printParamDetail(String paramName) throws RemoteException, ServiceException { printDebugMessage("printParamDetail", "Begin", 1); WsParameterDetails paramDetail = getParamDetail(paramName); // Print object System.out.println(paramDetail.getName() + "\t" + paramDetail.getType()); System.out.println(paramDetail.getDescription()); WsParameterValue[] valueList = paramDetail.getValues(); if (valueList != null) { for (int i = 0; i < valueList.length; i++) { System.out.print(valueList[i].getValue()); if (valueList[i].isDefaultValue()) { System.out.println("\tdefault"); } else { System.out.println(); } System.out.println("\t" + valueList[i].getLabel()); WsProperty[] valuePropertiesList = valueList[i].getProperties(); if (valuePropertiesList != null) { for (int j = 0; j < valuePropertiesList.length; j++) { System.out.println( "\t" + valuePropertiesList[j].getKey() + "\t" + valuePropertiesList[j].getValue()); } } } } printDebugMessage("printParamDetail", "End", 1); } /** * Get the status of a submitted job given its job identifier. * * @param jobid * The job identifier. * @return Job status as a string. * @throws IOException * @throws ServiceException */ public String checkStatus(String jobid) throws IOException, ServiceException { printDebugMessage("checkStatus", jobid, 1); this.srvProxyConnect(); // Ensure the service proxy exists return this.srvProxy.getStatus(jobid); } /** * Get details of the available result types for a job. * * @param jobId * Job identifier to check for results types. * @return Array of objects describing result types. * @throws ServiceException * @throws RemoteException */ public WsResultType[] getResultTypes(String jobId) throws ServiceException, RemoteException { printDebugMessage("getResultTypes", "Begin", 1); printDebugMessage("getResultTypes", "jobId: " + jobId, 2); WsResultType[] retVal = null; this.srvProxyConnect(); // Ensure the service proxy exists retVal = this.srvProxy.getResultTypes(jobId); printDebugMessage("getResultTypes", retVal.length + " result types", 2); printDebugMessage("getResultTypes", "End", 1); return retVal; } /** * Print details of the available result types for a job. * * @param jobId * Job identifier to check for result types. * @throws ServiceException * @throws RemoteException */ protected void printResultTypes(String jobId) throws ServiceException, RemoteException { printDebugMessage("printResultTypes", "Begin", 1); WsResultType[] typeList = getResultTypes(jobId); for (int i = 0; i < typeList.length; i++) { System.out.print(typeList[i].getIdentifier() + "\n\t" + typeList[i].getLabel() + "\n\t" + typeList[i].getDescription() + "\n\t" + typeList[i].getMediaType() + "\n\t" + typeList[i].getFileSuffix() + "\n"); } printDebugMessage("printResultTypes", "End", 1); } /** * Get the results for a job and save them to files. * * @param jobid * The job identifier. * @param outfile * The base name of the file to save the results to. If null the * jobid will be used. * @param outformat * The name of the data format to save, e.g. toolraw or toolxml. * If null all available data formats will be saved. * @return Array of filenames * @throws IOException * @throws javax.xml.rpc.ServiceException */ public String[] getResults(String jobid, String outfile, String outformat) throws IOException, javax.xml.rpc.ServiceException { printDebugMessage("getResults", "Begin", 1); printDebugMessage("getResults", "jobid: " + jobid + " outfile: " + outfile + " outformat: " + outformat, 2); String[] retVal = null; this.srvProxyConnect(); // Ensure the service proxy exists clientPoll(jobid); // Wait for job to finish // Set the base name for the output file. String basename = (outfile != null) ? outfile : jobid; // Get result types WsResultType[] resultTypes = getResultTypes(jobid); int retValN = 0; if (outformat == null) { retVal = new String[resultTypes.length]; } else { retVal = new String[1]; } for (int i = 0; i < resultTypes.length; i++) { printProgressMessage("File type: " + resultTypes[i].getIdentifier(), 2); // Get the results if (outformat == null || outformat.equals(resultTypes[i].getIdentifier())) { byte[] resultbytes = this.srvProxy.getResult(jobid, resultTypes[i].getIdentifier(), null); if (resultbytes == null) { System.err.println("Null result for " + resultTypes[i].getIdentifier() + "!"); } else { printProgressMessage("Result bytes length: " + resultbytes.length, 2); // Write the results to a file String result = new String(resultbytes); if (basename.equals("-")) { // STDOUT if (resultTypes[i].getMediaType().startsWith("text")) { // String System.out.print(result); } else { // Binary System.out.print(resultbytes); } } else { // File String filename = basename + "." + resultTypes[i].getIdentifier() + "." + resultTypes[i].getFileSuffix(); if (resultTypes[i].getMediaType().startsWith("text")) { // String writeFile(new File(filename), result); } else { // Binary writeFile(new File(filename), resultbytes); } retVal[retValN] = filename; retValN++; } } } } printDebugMessage("getResults", retVal.length + " file names", 2); printDebugMessage("getResults", "End", 1); return retVal; } /** * Submit a job to the service. * * @param params * Input parameters for the job. * @param content * Data to run the job on. * @return The job identifier. * @throws RemoteException * @throws ServiceException */ public String runApp(String email, String title, InputParameters params) throws RemoteException, ServiceException { printDebugMessage("runApp", "Begin", 1); printDebugMessage("runApp", "email: " + email + " title: " + title, 2); printDebugMessage("runApp", "params:\n" + objectFieldsToString(params), 2); String jobId = null; this.srvProxyConnect(); // Ensure the service proxy exists jobId = srvProxy.run(email, title, params); printDebugMessage("runApp", "jobId: " + jobId, 2); printDebugMessage("runApp", "End", 1); return jobId; } /** * Populate input parameters structure from command-line options. * * @param line * Command line options * @return input Input parameters structure for use with runApp(). * @throws IOException */ public InputParameters loadParams(CommandLine line) throws IOException { printDebugMessage("loadParams", "Begin", 1); InputParameters params = new InputParameters(); // Tool specific options if (line.hasOption("stype")) params.setStype(line.getOptionValue("stype")); else params.setStype("protein"); if (line.hasOption("p")) params.setProgram(line.getOptionValue("p")); if (line.hasOption("D")) { String[] dbList = line.getOptionValue("D").split(" +"); params.setDatabase(dbList); } if (line.hasOption("m")) params.setMatrix(line.getOptionValue("m")); if (line.hasOption("e")) params.setExp(line.getOptionValue("e")); else params.setExp("10"); if (line.hasOption("u") && line.hasOption("v")) { params.setMatch_scores(line.getOptionValue("u") + "," + line.getOptionValue("v")); } if (line.hasOption("o")) params.setGapopen(new Integer(line.getOptionValue("o"))); if (line.hasOption("x")) params.setGapext(new Integer(line.getOptionValue("x"))); if (line.hasOption("d")) params.setDropoff(new Integer(line.getOptionValue("d"))); if (line.hasOption("A")) params.setAlign(new Integer(line.getOptionValue("A"))); if (line.hasOption("s")) params.setScores(new Integer(line.getOptionValue("s"))); else params.setScores(new Integer(50)); if (line.hasOption("n")) params.setAlignments(new Integer(line.getOptionValue("n"))); else params.setAlignments(new Integer(50)); if (line.hasOption("g")) params.setGapalign(new Boolean(true)); if (line.hasOption("f")) params.setFilter(line.getOptionValue("f")); // if (line.hasOption("F")) params.setFormat(new Boolean(true)); if (line.hasOption("S")) params.setSeqrange(line.getOptionValue("S")); printDebugMessage("loadParams", "End", 1); return params; } /** * Submit a job using the command-line information to construct the input. * * @param cli * Command-line parameters. * @param inputSeq * Data input. * @throws ServiceException * @throws IOException */ public void submitJobFromCli(CommandLine cli, String inputSeq) throws ServiceException, IOException { // Create job submission parameters from command-line InputParameters params = this.loadParams(cli); params.setSequence(inputSeq); // Submit the job String email = null, title = null; if (cli.hasOption("email")) email = cli.getOptionValue("email"); if (cli.hasOption("title")) title = cli.getOptionValue("title"); String jobid = this.runApp(email, title, params); // For asynchronous mode if (cli.hasOption("async")) { System.out.println(jobid); // Output the job id. System.err.println("To get status: java -jar NCBIBlast_Axis1.jar --status --jobid " + jobid); } else { // In synchronous mode try to get the results this.printProgressMessage(jobid, 1); String[] resultFilenames = this.getResults(jobid, cli.getOptionValue("outfile"), cli.getOptionValue("outformat")); for (int i = 0; i < resultFilenames.length; i++) { if (resultFilenames[i] != null) { System.out.println("Wrote file: " + resultFilenames[i]); } } } } /** * Entry point for running as an application. * * @param args * list of command-line options * @throws IOException * @throws ServiceException * @throws ParseException */ public void main(String[] args) throws ServiceException, IOException, ParseException { int exitVal = 0; // Exit value int argsLength = args.length; // Number of command-line arguments // Configure the command-line options Options options = new Options(); // Common options for EBI clients addGenericOptions(options); options.addOption("multifasta", "multifasta", false, "Multiple fasta sequence input"); // Application specific options options.addOption("ids", "ids", false, "Get list of identifiers from result"); options.addOption("p", "program", true, "Program to use"); options.addOption("D", "database", true, "Database to search"); options.addOption("m", "matrix", true, "Scoring matrix"); options.addOption("e", "exp", true, "Expectation value threshold"); options.addOption("f", "filter", true, "Low complexity sequence filter"); options.addOption("g", "gapalign", true, "Perform gapped alignments"); options.addOption("A", "align", true, "Alignment format"); options.addOption("s", "scores", true, "Maximum number of scores to display"); options.addOption("n", "alignments", true, "Maximum number of alignments to display"); options.addOption("u", "match", true, "Match score"); options.addOption("v", "mismatch", true, "Mismatch score"); options.addOption("o", "gapopen", true, "Gap creation penalty"); options.addOption("x", "gapext", true, "Gap extension penalty"); options.addOption("d", "dropoff", true, "Drop off score"); options.addOption("seqrange", "seqrange", true, "Region in query sequence to use for search"); options.addOption("stype", "stype", true, "Sequence type"); options.addOption("sequence", "sequence", true, "Query sequence"); CommandLineParser cliParser = new GnuParser(); // Create the command // line parser // Create an instance of the client NCBIBlastClient client = new NCBIBlastClient(); // Parse the command-line CommandLine cli = cliParser.parse(options, args); // User asked for usage info if (argsLength == 0 || cli.hasOption("help")) { printUsage(); // System.exit(0); } // Modify output level according to the quiet and verbose options if (cli.hasOption("quiet")) { client.outputLevel--; } if (cli.hasOption("verbose")) { client.outputLevel++; } // Set debug level if (cli.hasOption("debugLevel")) { client.setDebugLevel(Integer.parseInt(cli.getOptionValue("debugLevel"))); } // Alternative service endpoint if (cli.hasOption("endpoint")) { client.setServiceEndPoint(cli.getOptionValue("endpoint")); } // Tool meta-data // List parameters if (cli.hasOption("params")) { client.printParams(); } // Details of a parameter else if (cli.hasOption("paramDetail")) { client.printParamDetail(cli.getOptionValue("paramDetail")); } // Job related actions else if (cli.hasOption("jobid")) { String jobid = cli.getOptionValue("jobid"); // Get results for job if (cli.hasOption("polljob")) { String[] resultFilenames = client.getResults(jobid, cli.getOptionValue("outfile"), cli.getOptionValue("outformat")); boolean resultContainContent = false; for (int i = 0; i < resultFilenames.length; i++) { if (resultFilenames[i] != null) { System.out.println("Wrote file: " + resultFilenames[i]); resultContainContent = true; } } if (resultContainContent == false) { System.err.println( "Error: requested result type " + cli.getOptionValue("outformat") + " not available!"); } } // Get entry Ids from result else if (cli.hasOption("ids")) { client.getResults(jobid, "-", "ids"); } // Get status of job else if (cli.hasOption("status")) { System.out.println(client.checkStatus(jobid)); } // Get result types for job else if (cli.hasOption("resultTypes")) { client.printResultTypes(jobid); } // Unknown... else { System.err.println("Error: jobid specified without related action option"); printUsage(); exitVal = 2; } } // Submit a job else if (cli.hasOption("email") && (cli.hasOption("sequence") || cli.getArgs().length > 0)) { // Input sequence, data file or entry identifier. String dataOption = (cli.hasOption("sequence")) ? cli.getOptionValue("sequence") : cli.getArgs()[0]; // Multi-fasta sequence input. if (cli.hasOption("multifasta")) { client.printDebugMessage("main", "Mode: multifasta", 11); int numSeq = 0; client.setFastaInputFile(dataOption); // Loop over input sequences, submitting each one. String fastaSeq = null; fastaSeq = client.nextFastaSequence(); client.printDebugMessage("main", "fastaSeq: " + fastaSeq, 12); while (fastaSeq != null) { numSeq++; client.submitJobFromCli(cli, fastaSeq); fastaSeq = client.nextFastaSequence(); } client.closeFastaFile(); client.printProgressMessage("Processed " + numSeq + " input sequences", 2); } // Entry identifier list. else if (dataOption.startsWith("@")) { client.printDebugMessage("main", "Mode: Id list", 11); int numId = 0; client.setIdentifierListFile(dataOption.substring(1)); // Loop over input sequences, submitting each one. String id = null; id = client.nextIdentifier(); while (id != null) { numId++; client.printProgressMessage("ID: " + id, 1); client.submitJobFromCli(cli, id); id = client.nextIdentifier(); } client.closeIdentifierListFile(); client.printProgressMessage("Processed " + numId + " input identifiers", 2); } // Submit a job else { client.printDebugMessage("main", "Mode: sequence", 11); client.submitJobFromCli(cli, new String(client.loadData(dataOption))); } } // Unknown action else { System.err.println("Error: unknown combination of arguments. See --help."); exitVal = 2; } // System.exit(exitVal); } }