// $HeadURL:
// svn+ssh://js163@orchestra.med.harvard.edu/svn/iccb/screensaver/trunk/.eclipse.prefs/codetemplates.xml
// $
// $Id$
//
// Copyright 2006 by the President and Fellows of Harvard College.
//
// Screensaver is an open-source project developed by the ICCB-L and NSRB labs
// at Harvard Medical School. This software is distributed under the terms of
// the GNU General Public License.
package edu.harvard.med.iccbl.screensaver.soaputils;
// Axis2-generated PUG SOAP classes
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.log4j.Logger;
import edu.harvard.med.screensaver.util.Pair;
import gov.nih.nlm.ncbi.pubchem.AnyKeyType;
import gov.nih.nlm.ncbi.pubchem.FormatType;
import gov.nih.nlm.ncbi.pubchem.GetIDList;
import gov.nih.nlm.ncbi.pubchem.GetOperationStatus;
import gov.nih.nlm.ncbi.pubchem.GetStandardizedCID;
import gov.nih.nlm.ncbi.pubchem.GetStandardizedStructure;
import gov.nih.nlm.ncbi.pubchem.GetStatusMessage;
import gov.nih.nlm.ncbi.pubchem.IdentitySearch;
import gov.nih.nlm.ncbi.pubchem.IdentitySearchOptions;
import gov.nih.nlm.ncbi.pubchem.IdentityType;
import gov.nih.nlm.ncbi.pubchem.InputStructure;
import gov.nih.nlm.ncbi.pubchem.PUGStub;
import gov.nih.nlm.ncbi.pubchem.Standardize;
import gov.nih.nlm.ncbi.pubchem.StatusType;
/**
* Convenience wrapper for the Axis classes generated for the Pubchem PUG Soap WSDL,<br>
* <a href="http://pubchem.ncbi.nlm.nih.gov/pug_soap/pug_soap_help.html">http://pubchem.ncbi.nlm.nih.gov/pug_soap/pug_soap_help.html</a><br>
* <br>
* Compatible with with Java classes generated by Axis2 1.4 with ADB databinding, requires
* the axis2 libraries found at<br>
* <a href="http://ws.apache.org/axis2/download.cgi">http://ws.apache.org/axis2/download.cgi</a><br>
* <br>
* To install, see the "install-pubchem" ant build task.<br>
* At this time, a small subset of the functionality has been implemented: the standardize function, and the
* identity search function.
*
* @author sde4
*/
public class PugSoapUtil
{
private static Logger log = Logger.getLogger(PugSoapUtil.class);
public static final int TRY_LIMIT = 50; // TODO: find out how the timelimit works
public static final int INTERVAL_BETWEEN_TRIES_MS = 2000; // TODO: find out how the timelimit works
public static class NonSuccessStatus extends Exception
{
private static final long serialVersionUID = 1L;
public StatusType status;
public String message;
private String context;
public NonSuccessStatus(String context, StatusType status, String message)
{
super("Non Success Status is returned: " + status + ", context: " + context + ", server status message: " + message);
this.context = context;
this.status = status;
this.message = message;
}
}
/**
* Use the default INTERVAL_BETWEEN_TRIES_MS, TRY_LIMIT
*/
public static int[] identitySearch(String smiles)
throws RemoteException,
InterruptedException,
NonSuccessStatus
{
return identitySearch(smiles, INTERVAL_BETWEEN_TRIES_MS, TRY_LIMIT);
}
/**
* Return the PUBChem CID's for compounds that are identical to this one
* including this one.
*
* @param smiles
* @return can return an empty array
* @throws RemoteException if the operation fails remotely; or if due to a
* non-success status
* @throws InterruptedException
* @see PUGStub#getIDList(GetIDList)
*/
public static int[] identitySearch(String smiles, int intervalMs, int tryLimit)
throws RemoteException,
InterruptedException,
NonSuccessStatus
{
String structure = smiles;
FormatType type = FormatType.eFormat_SMILES;
log.debug("get CIDS: " + structure + ", " + type);
PUGStub pug = getStub();
String standardizeKey = standardize(pug, structure, type);
StatusType status = getRunFinishedStatus(pug, standardizeKey, intervalMs, tryLimit);
if (status == StatusType.eStatus_Success) {
log.debug("found status: " + status);
String key = identitySearch(pug, standardizeKey);
status = getRunFinishedStatus(pug, key, intervalMs, tryLimit);
if (status == StatusType.eStatus_Success) {
GetIDList getIdlistReq = new GetIDList();
getIdlistReq.setListKey(key);
return pug.getIDList(getIdlistReq)
.getIDList()
.get_int();
} else {
throw new NonSuccessStatus("identitySearch",
status,
getStatusMessage(pug, key));
}
} else {
throw new NonSuccessStatus("standardize",
status,
getStatusMessage(pug,standardizeKey));
}
}
/**
* Use the default INTERVAL_BETWEEN_TRIES_MS, TRY_LIMIT
*/
public static String standardizeSmiles(String smiles)
throws RemoteException,
InterruptedException,
NonSuccessStatus
{
return standardizeSmiles(smiles, INTERVAL_BETWEEN_TRIES_MS, TRY_LIMIT);
}
public static String standardizeSmiles(String smiles, int intervalMs, int tryLimit)
throws RemoteException,
InterruptedException,
NonSuccessStatus
{
String structure = smiles;
FormatType type = FormatType.eFormat_SMILES;
log.debug("standardize: " + structure + ", " + type);
PUGStub pug = getStub();
String standardizeKey = standardize(pug, structure, type);
StatusType status = getRunFinishedStatus(pug, standardizeKey, intervalMs, tryLimit );
if (status == StatusType.eStatus_Success) {
log.debug("found status: " + status);
GetStandardizedStructure getStandardizedStructure = new GetStandardizedStructure();
getStandardizedStructure.setFormat(FormatType.eFormat_SMILES);
getStandardizedStructure.setStrKey(standardizeKey);
return pug.getStandardizedStructure(getStandardizedStructure)
.getStructure();
}
else {
throw new NonSuccessStatus("standardize",
status,
getStatusMessage(pug, standardizeKey));
}
}
public static Pair<String,int[]> standardizeAndIdentitySearch(String smiles, int intervalMs, int tryLimit)
throws RemoteException,
InterruptedException,
NonSuccessStatus
{
String structure = smiles;
FormatType type = FormatType.eFormat_SMILES;
log.debug("standardizeAndIdentitySearch: " + structure + ", " + type);
PUGStub pug = getStub();
String standardizeKey = standardize(pug, structure, type);
StatusType status = getRunFinishedStatus(pug, standardizeKey, intervalMs, tryLimit );
if (status == StatusType.eStatus_Success) {
log.debug("found status: " + status);
GetStandardizedStructure getStandardizedStructure = new GetStandardizedStructure();
getStandardizedStructure.setFormat(FormatType.eFormat_SMILES);
getStandardizedStructure.setStrKey(standardizeKey);
String standardizedSmiles = pug.getStandardizedStructure(getStandardizedStructure).getStructure();
String key = identitySearch(pug, standardizeKey);
status = getRunFinishedStatus(pug, key, intervalMs, tryLimit);
if (status == StatusType.eStatus_Success) {
GetIDList getIdlistReq = new GetIDList();
getIdlistReq.setListKey(key);
int[] cids = pug.getIDList(getIdlistReq)
.getIDList()
.get_int();
return Pair.newPair(standardizedSmiles, cids);
} else {
throw new NonSuccessStatus("identitySearch",
status,
getStatusMessage(pug, key));
}
}
else {
throw new NonSuccessStatus("standardize",
status,
getStatusMessage(pug, standardizeKey));
}
}
private static PUGStub getStub() throws AxisFault
{
PUGStub stub = new PUGStub();
//updateStub(stub, 500,1000);
return stub;
}
// NOTE: this is to try to avoid the INFO transport.http.HTTPSender:202 - Unable to sendViaPost to url[http://pubchem.ncbi.nlm.nih.gov/pug_soap/pug_soap.cgi]
// java.net.UnknownHostException: pubchem.ncbi.nlm.nih.gov
// from http://osdir.com/ml/axis-dev-ws.apache.org/2009-11/msg00168.html
private static void updateStub(org.apache.axis2.client.Stub stub, int
maxTotal, int maxPerHost)
{
MultiThreadedHttpConnectionManager httpConnectionManager = new
MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = httpConnectionManager.getParams();
if (params == null) {
params = new HttpConnectionManagerParams();
}
params.setMaxTotalConnections(maxTotal);
params.setDefaultMaxConnectionsPerHost(maxPerHost);
// extra, not prescribed -sde4
params.setConnectionTimeout(600000);
params.setSoTimeout(600000);
httpConnectionManager.setParams(params);
HttpClient httpClient = new HttpClient(httpConnectionManager);
ServiceClient serviceClient = stub._getServiceClient();
ConfigurationContext context =
serviceClient.getServiceContext().getConfigurationContext();
context.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
}
private static int getStandardizedCID(PUGStub pug, String standardizeKey)
throws RemoteException
{
GetStandardizedCID getStandardizedCID = new GetStandardizedCID();
getStandardizedCID.setStrKey(standardizeKey);
int cid = pug.getStandardizedCID(getStandardizedCID)
.getCID();
return cid;
}
private static String inputStructure(PUGStub pug,
String structure,
FormatType type) throws RemoteException
{
InputStructure inputStructure = new InputStructure();
inputStructure.setStructure(structure);
inputStructure.setFormat(type);
String structureKey = pug.inputStructure(inputStructure)
.getStrKey();
log.debug("key: " + structureKey);
return structureKey;
}
private static String standardize(PUGStub pug,
String structure,
FormatType type) throws RemoteException
{
Standardize standardize = new Standardize();
standardize.setStrKey(inputStructure(pug, structure, type));
return pug.standardize(standardize)
.getStrKey();
}
private static String getStatusMessage(PUGStub pug, String key)
{
GetStatusMessage req6 = new GetStatusMessage();
AnyKeyType anyKey = new AnyKeyType();
anyKey.setAnyKey(key);
req6.setGetStatusMessage(anyKey);
try {
return pug.getStatusMessage(req6)
.getMessage();
}
catch (RemoteException e) {
log.warn("Server status request failed, unable to provide a status message: " + e.getMessage());
log.info("Server Status request failed, unable to provide a status message",e);
return "Server status request failed, unable to provide a status message: " + e.getMessage();
}
}
private static String identitySearch(PUGStub pug, String standardizeKey)
throws RemoteException
{
IdentitySearch iReq = new IdentitySearch();
iReq.setStrKey(standardizeKey);
IdentitySearchOptions isOpt = new IdentitySearchOptions();
isOpt.setEIdentity(IdentityType.eIdentity_SameIsotopeNonconflictStereo);
iReq.setIdOptions(isOpt);
String key = pug.identitySearch(iReq)
.getListKey();
return key;
}
private static StatusType getRunFinishedStatus(PUGStub pug,
String key,
int intervalMs,
int tryLimit)
throws NonSuccessStatus,
InterruptedException, RemoteException
{
GetOperationStatus statusRequest = new GetOperationStatus();
AnyKeyType anyKey = new AnyKeyType();
anyKey.setAnyKey(key);
statusRequest.setGetOperationStatus(anyKey);
StatusType status;
int _try = 0;
while ((status = pug.getOperationStatus(statusRequest)
.getStatus()) == StatusType.eStatus_Running ||
status == StatusType.eStatus_Queued) {
if (_try++ > tryLimit) {
throw new NonSuccessStatus("try limit reached", null, "try limit reached: " + tryLimit);
}
log.debug("Waiting for standardize to finish...");
Thread.sleep(intervalMs);
}
return status;
}
// private static void similaritySearch() throws Exception
// {
// PUGStub soap = new PUGStub();
//
// // input o-bromopyridine in SMILES format
// String smiles = "CC1=C(C(=O)N(N1C)C2=CC=CC=C2)/C=C\\\\C3=C(C=C(C=C3)Cl)Cl";
// InputStructure inputStructure = new InputStructure();
// inputStructure.setStructure(smiles);
// inputStructure.setFormat(FormatType.eFormat_SMILES);
// String strKey = soap.inputStructure(inputStructure)
// .getStrKey();
// System.out.println("StrKey = " + strKey);
//
// // Initialize similarity search @ 100%
// SimilaritySearch2D similaritySearchArg = new SimilaritySearch2D();
// similaritySearchArg.setStrKey(strKey);
// SimilaritySearchOptions simSearchOptions = new SimilaritySearchOptions();
// simSearchOptions.setThreshold(100);
// LimitsType limitsTypeOption = new LimitsType();
// limitsTypeOption.setSeconds(60);
// limitsTypeOption.setMaxRecords(500);
// similaritySearchArg.setLimits(limitsTypeOption);
// similaritySearchArg.setSimOptions(simSearchOptions);
// String listKey = soap.similaritySearch2D(similaritySearchArg)
// .getListKey();
// System.out.println("ListKey = " + listKey);
//
// // Wait for the search to finish
// String key = listKey;
// GetOperationStatus statusRequest = new GetOperationStatus();
// AnyKeyType anyKey = new AnyKeyType();
// anyKey.setAnyKey(key);
// statusRequest.setGetOperationStatus(anyKey);
//
// StatusType status;
// while ((status = soap.getOperationStatus(statusRequest)
// .getStatus()) == StatusType.eStatus_Running ||
// status == StatusType.eStatus_Queued) {
// log.debug("Waiting for search to finish...");
// Thread.sleep(2000);
// }
//
// // On success, get the results as an Entrez URL
// if (status == StatusType.eStatus_Success ||
// status == StatusType.eStatus_TimeLimit ||
// status == StatusType.eStatus_HitLimit) {
// if (status == StatusType.eStatus_TimeLimit) {
// System.out.println("Warning: time limit reached before entire db searched");
// }
// else if (status == StatusType.eStatus_HitLimit) {
// System.out.println("Warning: hit limit reached before entire db searched");
// }
//
// GetListItemsCount countRequest = new GetListItemsCount();
// countRequest.setListKey(listKey);
// System.out.println("Success! # hits = " +
// soap.getListItemsCount(countRequest)
// .getCount());
//
// GetIDList getIdListReq = new GetIDList();
// getIdListReq.setListKey(listKey);
//
// ArrayOfInt cids = soap.getIDList(getIdListReq)
// .getIDList();
// for (int x : cids.get_int()) {
// System.out.println("CID: " + x);
// }
//
//
// GetEntrezKey getEntrezKeyReq = new GetEntrezKey();
// getEntrezKeyReq.setListKey(listKey);
// GetEntrezUrl getEntrezUrl = new GetEntrezUrl();
// getEntrezUrl.setEntrezKey(soap.getEntrezKey(getEntrezKeyReq)
// .getEntrezKey());
// System.out.println("Entrez URL: " + soap.getEntrezUrl(getEntrezUrl)
// .getUrl());
//
// // EntrezKey entrezKey = soap.getEntrezKey(listKey);
// // String URL = soap.getEntrezUrl(entrezKey);
// // System.out.println("Entrez URL = " + URL);
// }
// else {
// GetStatusMessage req6 = new GetStatusMessage();
// req6.setGetStatusMessage(anyKey);
// System.out.println("Error: " + soap.getStatusMessage(req6)
// .getMessage());
// }
// }
}