package com.github.lindenb.jvarkit.util.biomart; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringWriter; import java.io.Writer; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import htsjdk.tribble.readers.AsciiLineReader; import htsjdk.tribble.readers.LineReader; public class BiomartQuery { private String url="http://www.biomart.org/biomart/martservice/result"; private boolean uniqRows=true; private String charset="UTF-8"; private String dataSetConfigVersion="0.6"; private String dataSetName="hsapiens_gene_ensembl"; private List<String> attributes=Collections.emptyList(); private Map<String,String> filters=new LinkedHashMap<String,String>(); private boolean showHeader=false; public BiomartQuery() { } public void setShowHeader(boolean showHeader) { this.showHeader = showHeader; } public boolean isShowingHeader() { return showHeader; } public void setServiceUrl(String url) { this.url = url; } public String getServiceUrl() { return url; } public String getDataSetConfigVersion() { return dataSetConfigVersion; } public String getDataSetName() { return dataSetName; } public void setDataSetConfigVersion(String dataSetConfigVersion) { this.dataSetConfigVersion = dataSetConfigVersion; } public void setDataSetName(String dataSetName) { this.dataSetName = dataSetName; } public boolean isUniqRows() { return uniqRows; } public void setUniqRows(boolean uniqRows) { this.uniqRows = uniqRows; } public String getCharSet() { return charset; } public void setCharset(String charset) { this.charset = charset; } public List<String> getAttributes() { return attributes; } public void setAttributes(List<String> attributes) { this.attributes = new ArrayList<String>(attributes); } public void setAttributes(String...atts) { this.attributes = Arrays.asList(atts); } public void addFilter(String name,String value) { this.filters.put(name, value); } public Map<String,String> getFilters() { return this.filters; } protected void writeFilters(XMLStreamWriter w) throws XMLStreamException { Map<String,String> m=this.getFilters(); for(String f:m.keySet()) { w.writeEmptyElement("Filter"); w.writeAttribute("name", f); w.writeAttribute("value", f); } } protected void writeAttributes(XMLStreamWriter w) throws XMLStreamException { for(String att:getAttributes()) { w.writeEmptyElement("Attribute"); w.writeAttribute("name", att); } } public void write(XMLStreamWriter w) throws XMLStreamException { w.writeStartDocument(getCharSet(), "1.0"); w.writeStartElement("Query"); w.writeAttribute("virtualSchemaName", "default"); w.writeAttribute("formatter", "TSV"); w.writeAttribute("header", isShowingHeader()?"1":"0"); w.writeAttribute("uniqueRows",isUniqRows()?"0":"1"); w.writeAttribute("count", "0"); w.writeAttribute("datasetConfigVersion",getDataSetConfigVersion()); w.writeStartElement("Dataset"); w.writeAttribute("name",getDataSetName()); w.writeAttribute("interface", "default"); writeFilters(w); writeAttributes(w); w.writeEndElement(); w.writeEndElement(); w.writeEndDocument(); w.flush(); } public final void write(Writer stream) throws XMLStreamException { XMLOutputFactory xof=XMLOutputFactory.newFactory(); XMLStreamWriter w=xof.createXMLStreamWriter(stream); write(w); w.flush(); w.close(); } public String getXmlString() { try { StringWriter sw=new StringWriter(); write(sw); return sw.toString(); } catch (XMLStreamException e) { throw new RuntimeException(e); } } @Override public String toString() { return getXmlString(); } public String getMd5() throws Exception { MessageDigest complete = MessageDigest.getInstance("MD5"); complete.update(getXmlString().getBytes()); complete.update(getServiceUrl().getBytes()); byte b[]=complete.digest(); StringBuilder result = new StringBuilder(); for (int i=0; i < b.length; i++) { result.append( Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 )); } return result.toString(); } public LineReader execute() throws IOException { URLConnection connection = new URL(this.getServiceUrl()).openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Accept-Charset", this.getCharSet()); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + this.getCharSet()); if(connection instanceof HttpURLConnection ) { HttpURLConnection httpConnection = (HttpURLConnection)connection; httpConnection.setRequestMethod("POST"); httpConnection.setInstanceFollowRedirects(true); } String q="query="+URLEncoder.encode(this.getXmlString(),this.getCharSet()); OutputStream output = null; try { output = connection.getOutputStream(); output.write(q.getBytes(this.getCharSet())); output.flush(); } finally { if (output != null) try { output.close(); } catch (IOException logOrIgnore) {logOrIgnore.printStackTrace();} } InputStream response = connection.getInputStream(); AsciiLineReader r=new AsciiLineReader(response); return r; } }