Show
Ignore:
Timestamp:
08/19/09 05:53:32 (3 years ago)
Author:
jgao
Message:

IDMapperBiomart refactor to clean the interface

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/corelib/src/org/bridgedb/webservice/biomart/BiomartStub.java

    r156 r161  
    1919 
    2020import java.io.BufferedReader; 
    21 import java.io.InputStream; 
    22 import java.io.InputStreamReader; 
    2321import java.io.IOException; 
    24 import java.io.OutputStream; 
    25 import java.io.PrintStream; 
    26  
    27 import java.net.URL; 
    28 import java.net.URLConnection; 
    2922 
    3023import java.util.HashMap; 
     24import java.util.HashSet; 
     25import java.util.Iterator; 
    3126import java.util.Map; 
     27import java.util.Set; 
    3228import java.util.Vector; 
    3329 
    34 import javax.xml.parsers.DocumentBuilder; 
    35 import javax.xml.parsers.DocumentBuilderFactory; 
    3630import javax.xml.parsers.ParserConfigurationException; 
    3731 
    38 import org.w3c.dom.Document; 
    39 import org.w3c.dom.NamedNodeMap; 
    40 import org.w3c.dom.NodeList; 
     32import org.bridgedb.DataSource; 
     33import org.bridgedb.IDMapperException; 
     34import org.bridgedb.Xref; 
     35import org.bridgedb.file.IDMappingReaderFromDelimitedReader; 
     36import org.bridgedb.webservice.biomart.util.Attribute; 
     37import org.bridgedb.webservice.biomart.util.BiomartClient; 
     38import org.bridgedb.webservice.biomart.util.Database; 
     39import org.bridgedb.webservice.biomart.util.Dataset; 
     40import org.bridgedb.webservice.biomart.util.Filter; 
     41import org.bridgedb.webservice.biomart.util.XMLQueryBuilder; 
    4142 
    4243import org.xml.sax.SAXException; 
    4344 
    4445/** 
    45  * BioMart service class, adapted from BioMart client in Cytoscape. 
     46 * Cache for SynergizerClient 
     47 * @author gjj 
    4648 */ 
    47 public final class BiomartStub { 
    48     public static final String defaultBaseURL = "http://www.biomart.org/biomart/martservice"; 
    49      
    50     private final String baseURL; 
    51     private static final String RESOURCE = "/org/bridgedb/webservice/biomart/filterconversion.txt"; 
    52  
    53     //private Map<String, Map<String, String>> databases = null; 
    54     private Map<String, Database> databases = null; 
    55  
    56     private Map<String, Dataset> datasets = new HashMap(); 
    57     private Map<String, Vector<Dataset>> mapDbDss = new HashMap(); 
    58     private Map<String, Map<String, Filter>> mapDsFilters = new HashMap(); 
    59     private Map<String, Map<String, Attribute>> mapDsAttrs = new HashMap(); 
    60  
    61     private Map<String, Map<String, String>> filterConversionMap; 
    62  
    63     private static final int BUFFER_SIZE = 81920; 
    64  
    65     // one instance per base url 
     49public class BiomartStub { 
     50    public static final String defaultBaseURL 
     51            = BiomartClient.defaultBaseURL; 
     52 
     53    // cache data 
     54//    private Map<String,Map<String,Map<String,Set<String>>>> 
     55//            mapAuthSpeciesDomainRange = null; 
     56 
     57    // one instance per url 
    6658    private static Map<String, BiomartStub> instances = new HashMap(); 
    6759 
    6860    /** 
    69      * Get a BioMartStub with the default base URL. 
    70      * @return BiomartStub 
    71      * @throws IOException if failed to read local resource 
     61     * 
     62     * @return SynergizerStub with the default server url 
     63     * @throws IOException if failed to connect 
    7264     */ 
    7365    public static BiomartStub getInstance() throws IOException { 
     
    7668 
    7769    /** 
    78      * Get a BioMartStub with the base URL. 
    79      * @param baseURL base URL of BioMart 
    80      * @return BioMartStub 
    81      * @throws IOException if failed to read local resource 
    82      */ 
    83     public static BiomartStub getInstance(String baseURL) throws IOException { 
    84         if (baseURL==null) { 
     70     * 
     71     * @param baseUrl server url 
     72     * @return SynergizerStub from the server 
     73     * @throws IOException if failed to connect 
     74     */ 
     75    public static BiomartStub getInstance(String baseUrl) throws IOException { 
     76        if (baseUrl==null) { 
    8577            throw new IllegalArgumentException("base url cannot be null"); 
    8678        } 
    8779 
    88         BiomartStub instance = instances.get(baseURL); 
     80        BiomartStub instance = instances.get(baseUrl); 
    8981        if (instance==null) { 
    90             instance = new BiomartStub(baseURL); 
    91             instances.put(baseURL, instance); 
     82            instance = new BiomartStub(baseUrl); 
     83            instances.put(baseUrl, instance); 
    9284        } 
    9385 
    9486        return instance; 
    95    } 
    96  
    97  
    98     /** 
    99      * Creates a new BiomartStub object from given URL. 
    100      * 
    101      * @param baseURL  DOCUMENT ME! 
    102      * @throws IOException if failed to read local resource 
    103      */ 
    104     private BiomartStub(String baseURL) throws IOException { 
    105         this.baseURL = baseURL + "?"; 
    106         loadConversionFile(); 
    107     } 
    108  
    109     /** 
    110      * Conversion map from filter to attribute. 
    111      * @throws IOException if failed to read local resource 
    112      */ 
    113     private void loadConversionFile() throws IOException { 
    114         filterConversionMap = new HashMap<String, Map<String, String>>(); 
    115  
    116         InputStreamReader inFile = new InputStreamReader(this.getClass().getResource(RESOURCE).openStream()); 
    117  
    118         BufferedReader inBuffer = new BufferedReader(inFile); 
    119  
    120         String line; 
    121         String trimed; 
    122         String oldName = null; 
    123         Map<String, String> oneEntry = new HashMap<String, String>(); 
    124  
    125         String[] dbparts; 
    126  
    127         while ((line = inBuffer.readLine()) != null) { 
    128             trimed = line.trim(); 
    129             dbparts = trimed.split("\\t"); 
    130  
    131             if (dbparts[0].equals(oldName) == false) { 
    132                 oneEntry = new HashMap<String, String>(); 
    133                 oldName = dbparts[0]; 
    134                 filterConversionMap.put(oldName, oneEntry); 
     87    } 
     88 
     89    private BiomartClient client; 
     90 
     91    /** 
     92     * 
     93     * @param baseUrl server url. 
     94     * @throws IOException if failed to connect. 
     95     */ 
     96    private BiomartStub(String baseUrl) throws IOException { 
     97        client = new BiomartClient(baseUrl); 
     98    } 
     99 
     100    /** 
     101     * 
     102     * @return available marts 
     103     * @throws IDMapperException if failed 
     104     */ 
     105    public Set<String> availableMarts() throws IDMapperException { 
     106        Map<String, Database> marts; 
     107        try { 
     108            marts = client.getRegistry(); 
     109        } catch (IOException e) { 
     110            throw new IDMapperException(e); 
     111        } catch (ParserConfigurationException e) { 
     112            throw new IDMapperException(e); 
     113        } catch (SAXException e) { 
     114            throw new IDMapperException(e); 
     115        } 
     116 
     117        Set<String> visibleMarts = new HashSet(); 
     118        for (Database db : marts.values()) { 
     119            if (db.visible()) { 
     120                visibleMarts.add(db.getName()); 
    135121            } 
    136  
    137             oneEntry.put(dbparts[1], dbparts[2]); 
    138         } 
    139  
    140         inFile.close(); 
    141         inBuffer.close(); 
    142     } 
    143  
    144     /** 
    145      * Convert filter to attribute according to the conversion file. 
    146      * @param dsName dataset name. 
    147      * @param dbName database name 
    148      * @param filterID filter ID 
    149      * @return converted attribute 
    150      */ 
    151     public Attribute filterToAttributeName(String dsName, String dbName, 
    152                 String filterID) { 
    153         if (filterConversionMap.get(dbName) == null) { 
     122        } 
     123 
     124        return visibleMarts; 
     125    } 
     126 
     127    /** 
     128     * 
     129     * @param mart mart name 
     130     * @return mart display name or null if not exist 
     131     * @throws IDMapperException if failed to connect 
     132     */ 
     133    public String martDisplayName(String mart) { 
     134        if (mart==null) { 
    154135            return null; 
    155         } else { 
    156             String attrName = filterConversionMap.get(dbName).get(filterID); 
    157             return this.getAttribute(dsName, attrName); 
    158         } 
    159     } 
    160  
    161     /** 
    162      *  Get the registry information from the base URL. 
    163      * 
    164      * @return  Map of registry information.  Key value is "name" field. 
    165      * @throws ParserConfigurationException if failed new document builder 
    166      * @throws SAXException if failed to parse registry 
    167      * @throws IOException if failed to read from URL 
    168      */ 
    169     public Map<String, Database> getRegistry() 
    170             throws IOException, ParserConfigurationException, SAXException { 
    171         // If already loaded, just return it. 
    172         if (databases != null) 
    173             return databases; 
    174  
    175         // Initialize database map. 
    176         databases = new HashMap<String, Database>(); 
    177  
    178         // Prepare URL for the registry status 
    179         final String reg = "type=registry"; 
    180         final URL targetURL = new URL(baseURL + reg); 
    181  
    182         // Get the result as XML document. 
    183         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    184         final DocumentBuilder builder = factory.newDocumentBuilder(); 
    185  
    186         InputStream is = getInputStream(targetURL); 
    187  
    188         final Document registry = builder.parse(is); 
    189  
    190         // Extract each datasource 
    191         NodeList locations = registry.getElementsByTagName("MartURLLocation"); 
    192         int locSize = locations.getLength(); 
    193         NamedNodeMap attrList; 
    194         int attrLen; 
    195         String dbID; 
    196  
    197         for (int i = 0; i < locSize; i++) { 
    198             attrList = locations.item(i).getAttributes(); 
    199             attrLen = attrList.getLength(); 
    200  
    201             // First, get the key value 
    202             dbID = attrList.getNamedItem("name").getNodeValue(); 
    203  
    204             Map<String, String> entry = new HashMap<String, String>(); 
    205  
    206             for (int j = 0; j < attrLen; j++) { 
    207                 entry.put(attrList.item(j).getNodeName(), attrList.item(j).getNodeValue()); 
    208             } 
    209  
    210             databases.put(dbID, new Database(dbID,entry)); 
    211         } 
    212  
    213         is.close(); 
    214         is = null; 
    215  
    216         return databases; 
    217     } 
    218  
    219     /** 
    220      * Get available datasets of a mart/database. 
    221      * @param martName mart name 
    222      * @return {@link Vector} of available datasets 
    223      * @throws IOException if failed to read 
    224      */ 
    225     public Vector<Dataset> getAvailableDatasets(final String martName) 
    226             throws IOException { 
    227         Vector<Dataset> result = mapDbDss.get(martName); 
    228         if (result!=null) { 
    229             return result; 
    230         } 
    231  
    232         try { 
    233             getRegistry(); 
    234         } catch (ParserConfigurationException e) { 
    235             e.printStackTrace(); 
    236         } catch (SAXException e) { 
    237             e.printStackTrace(); 
    238         } 
    239  
    240         //final Map<String, String> datasources = new HashMap<String, String>(); 
    241         result = new Vector(); 
    242  
    243         Database database = databases.get(martName); 
    244  
    245         if (database==null) { 
     136        } 
     137 
     138        Database db = client.getMart(mart); 
     139        return db==null?null:db.displayName(); 
     140    } 
     141 
     142    /** 
     143     * 
     144     * @param authority mart name 
     145     * @return available datasets from this mart 
     146     * @throws IDMapperException if failed 
     147     */ 
     148    public Set<String> availableDatasets(String mart) 
     149            throws IDMapperException { 
     150        if (mart==null) { 
     151            return new HashSet(0); 
     152        } 
     153 
     154        if (!availableMarts().contains(mart)) { 
     155            return new HashSet(0); 
     156        } 
     157 
     158        Map<String,Dataset> datasets; 
     159        try { 
     160            datasets = client.getAvailableDatasets(mart); 
     161        } catch (IOException e) { 
     162            throw new IDMapperException(e); 
     163        } 
     164 
     165        return datasets.keySet(); 
     166    } 
     167 
     168     /** 
     169     * 
     170     * @param dataset dataset name 
     171     * @return dataset display name or null if not exist 
     172     * @throws IDMapperException if failed to connect 
     173     */ 
     174    public String datasetDisplayName(String dataset) { 
     175        if (dataset==null) { 
    246176            return null; 
    247177        } 
    248178 
    249         Map<String, String> detail = database.getParam(); 
    250  
    251         String urlStr = "http://" + detail.get("host") + ":" + detail.get("port") 
    252                         + detail.get("path") + "?type=datasets&mart=" + detail.get("name"); 
    253         //System.out.println("DB name = " + martName + ", Target URL = " + urlStr + "\n"); 
    254  
    255         URL url = new URL(urlStr); 
    256         InputStream is = getInputStream(url); 
    257  
    258         BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
    259         String s; 
    260  
    261         String[] parts; 
    262  
    263         while ((s = reader.readLine()) != null) { 
    264             parts = s.split("\\t"); 
    265  
    266             if ((parts.length > 4) && parts[3].equals("1")) { 
    267                 Dataset dataset = new Dataset(parts[1], parts[2], database); 
    268                 result.add(dataset); 
    269                 //datasourceMap.put(parts[1], martName); 
    270                 datasets.put(parts[1], dataset); 
    271             } 
    272         } 
    273  
    274         is.close(); 
    275         reader.close(); 
    276         reader = null; 
    277         is = null; 
    278  
    279         mapDbDss.put(martName, result); 
    280  
    281         return result; 
    282     } 
    283  
    284     /** 
    285      * Get filters for a dataset. 
    286      * @param datasetName name of data set 
    287      * @return filters 
    288      * @throws IOException if failed to read 
    289      */ 
    290     public Map<String, Filter> getFilters(String datasetName) 
    291         throws IOException { 
    292         if (datasetName==null) { 
    293             throw new IllegalArgumentException("Dataset name cannot be null"); 
    294         } 
    295  
    296         if (mapDsFilters.get(datasetName)!=null) { 
    297             return mapDsFilters.get(datasetName); 
    298         } 
    299  
    300         Map<String, Filter> filters = new HashMap(); 
    301  
    302         Dataset dataset = getDataset(datasetName); 
    303         if (dataset==null) { 
    304             return filters; 
    305         } 
    306  
    307         Database database = dataset.getDatabase(); 
    308  
    309         Map<String, String> detail = database.getParam(); 
    310  
    311         String urlStr = "http://"  
    312                         + detail.get("host") + ":" 
    313                         + detail.get("port") 
    314                         + detail.get("path") 
    315                         + "?virtualschema=" 
    316                         + detail.get("serverVirtualSchema") 
    317                         + "&type=filters&dataset=" 
    318                         + datasetName; 
    319  
    320         //System.out.println("Dataset name = " + datasetName + ", Target URL = " 
    321         //                      + urlStr + "\n"); 
    322         URL url = new URL(urlStr); 
    323         InputStream is = getInputStream(url); 
    324  
    325         BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
    326         String s; 
    327  
    328         String[] parts; 
    329  
    330         while ((s = reader.readLine()) != null) { 
    331             parts = s.split("\\t"); 
    332  
    333             if ((parts.length > 1)) { 
    334                 if ((parts[1].contains("ID(s)") 
    335                             || parts[1].contains("Accession(s)") 
    336                             || parts[1].contains("IDs")) 
    337                          && (parts[0].startsWith("with_") == false) 
    338                          && (parts[0].endsWith("-2") == false) 
    339                          || parts.length>6 
    340                          && parts[5].equals("id_list")) { 
    341                     //filters.put(parts[1], parts[0]); 
    342                     filters.put(parts[0], new Filter(parts[0], parts[1])); 
    343                     // System.out.println("### Filter Entry = " + parts[1] + " = " + parts[0]); 
     179        Dataset ds = client.getDataset(dataset); 
     180        return ds==null?null:ds.displayName(); 
     181    } 
     182 
     183    /** 
     184     * 
     185     * @param mart mart name 
     186     * @param dataset dataset name 
     187     * @return available filters / source id types of the dataset from this 
     188     *         mart 
     189     * @throws IDMapperException if failed 
     190     */ 
     191    public Set<String> availableFilters(final String mart, 
     192            final String dataset) throws IDMapperException { 
     193        if (mart==null || dataset==null) { 
     194            return new HashSet(0); 
     195        } 
     196 
     197        if (!availableDatasets(mart).contains(dataset)) { 
     198            return new HashSet(0); 
     199        } 
     200 
     201        Map<String,Filter> filters; 
     202        try { 
     203            filters = client.getFilters(dataset); 
     204        } catch (IOException e) { 
     205            throw new IDMapperException(e); 
     206        } 
     207 
     208        return filters.keySet(); 
     209    } 
     210 
     211    /** 
     212     * 
     213     * @param mart mart name 
     214     * @param dataset dataset name 
     215     * @return attribute names / target id types of the dataset from this 
     216     *         mart 
     217     * @throws IDMapperException if failed. 
     218     */ 
     219    public Set<String> availableAttributes(final String mart, 
     220            final String dataset, boolean idOnly) throws IDMapperException { 
     221 
     222        if (mart==null || dataset==null) { 
     223            return new HashSet(0); 
     224        } 
     225 
     226        if (!availableDatasets(mart).contains(dataset)) { 
     227            return new HashSet(0); 
     228        } 
     229 
     230        Map<String,Attribute> attributes; 
     231        try { 
     232            attributes = client.getAttributes(dataset); 
     233        } catch (IOException e) { 
     234            throw new IDMapperException(e); 
     235        } 
     236 
     237        Set<String> result; 
     238        if (idOnly) { 
     239            result = new HashSet(); 
     240            for (String name : attributes.keySet()) { 
     241                String displayName = client.getAttribute(dataset, name).getDisplayName(); 
     242                if (displayName.endsWith("ID") 
     243                        || displayName.endsWith("Accession") 
     244                        || name.endsWith("id") 
     245                        || name.endsWith("accession")) { 
     246                    result.add(name); 
    344247                } 
    345248            } 
    346         } 
    347  
    348         is.close(); 
    349         reader.close(); 
    350         reader = null; 
    351         is = null; 
    352  
    353         mapDsFilters.put(datasetName, filters); 
    354  
    355         return filters; 
    356     } 
    357  
    358     /** 
    359      * Get attributes. 
    360      * @param datasetName dataset name 
    361      * @return Map of attribute name to attributes 
    362      * @throws IOException if failed to read 
    363      */ 
    364     public Map<String, Attribute> getAttributes(String datasetName) throws IOException { 
    365         if (datasetName==null) { 
    366             throw new java.lang.IllegalArgumentException("Dataset name cannot be null"); 
    367         } 
    368  
    369         if (mapDsAttrs.get(datasetName)!=null) { 
    370             return mapDsAttrs.get(datasetName); 
    371         } 
    372  
    373         Map<String, Attribute> attributes = new HashMap<String, Attribute>(); 
    374  
    375         Dataset dataset = getDataset(datasetName); 
    376         if (dataset==null) { 
    377             return attributes; 
    378         } 
    379  
    380         Database database = dataset.getDatabase(); 
    381  
    382         Map<String, String> detail = database.getParam(); 
    383  
    384         String urlStr = "http://" + detail.get("host") + ":" + detail.get("port") 
    385                         + detail.get("path") + "?virtualschema=" 
    386                         + detail.get("serverVirtualSchema") + "&type=attributes&dataset=" 
    387                         + datasetName; 
    388  
    389         //System.out.println("Dataset name = " + datasetName + ", Target URL = " + urlStr + "\n"); 
    390         URL url = new URL(urlStr); 
    391         InputStream is = getInputStream(url); 
    392  
    393         BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
    394         String s; 
    395  
    396         String displayName; 
    397  
    398         String[] parts; 
    399  
    400         while ((s = reader.readLine()) != null) { 
    401             parts = s.split("\\t"); 
    402  
    403             if (parts.length == 0) 
    404                 continue; 
    405  
    406             if (parts.length == 4) { 
    407                 displayName = parts[3] + ": " + parts[1]; 
    408             } else if (parts.length > 1) { 
    409                 displayName = parts[1]; 
    410             } else { 
    411                 displayName = ""; 
     249        } else { 
     250            result = new HashSet(attributes.keySet()); 
     251        } 
     252 
     253        return result; 
     254    } 
     255 
     256    /** 
     257     *  
     258     * @param mart mart name 
     259     * @param dataset dataset name 
     260     * @param filter filter name / source id type 
     261     * @param attributes attribute names / target id types 
     262     * @param ids source ids to be translated 
     263     * @return map from source id to target ids 
     264     *         key: source id 
     265     *         value: corresponding target ids 
     266     * @throws IDMapperException 
     267     */ 
     268    public Map<String,Set<String>[]> translate(final String mart, 
     269            final String dataset, final String filter, 
     270            final String[] attributes, final Set<String> ids) 
     271            throws IDMapperException { 
     272        int nAttr = attributes.length; 
     273        Attribute[] attrs = new Attribute[nAttr+1]; 
     274 
     275        // prepare attributes 
     276        int iattr = 0; 
     277        for (String attr : attributes) { 
     278            attrs[iattr++] = client.getAttribute(dataset, attr); 
     279        } 
     280        attrs[nAttr] = client.filterToAttribute(dataset, filter); 
     281 
     282        // prepare filters 
     283        StringBuilder sb = new StringBuilder(); 
     284        for (String str : ids) { 
     285            sb.append(str); 
     286            sb.append(","); 
     287        } 
     288 
     289        int len = sb.length(); 
     290        if (len>0) { 
     291            sb.deleteCharAt(len-1); 
     292        } 
     293 
     294        Map<String, String> queryFilter = new HashMap(1); 
     295        queryFilter.put(filter, sb.toString()); 
     296 
     297        // build query string 
     298        String query = XMLQueryBuilder.getQueryString(dataset, attrs, queryFilter); 
     299 
     300        // query 
     301        BufferedReader bfr = null; 
     302        try { 
     303            bfr = client.sendQuery(query); 
     304            if (!bfr.ready()) 
     305                throw new IDMapperException("Query failed"); 
     306        } catch (IOException e) { 
     307            throw new IDMapperException(e); 
     308        } 
     309 
     310        if (bfr==null) { 
     311            return new HashMap(0); 
     312        } 
     313 
     314        // read id mapping 
     315        Map<String,Set<String>[]> result = new HashMap(); 
     316        try { 
     317            bfr.readLine(); 
     318            String line; 
     319            while ((line = bfr.readLine())!=null) { 
     320                String[] strs = line.split("\t"); 
     321                if (strs.length!=nAttr+1) 
     322                    continue; // because the last one is the src id 
     323                String src = strs[nAttr]; 
     324                Set<String>[] tgt = result.get(src); 
     325                if (tgt==null) { 
     326                    tgt = new Set[nAttr]; 
     327                    for (int i=0; i<nAttr; i++) { 
     328                        tgt[i] = new HashSet(); 
     329                    } 
     330                    result.put(src, tgt); 
     331                } 
     332 
     333                for (int i=0; i<nAttr; i++) { 
     334                    String str = strs[i]; 
     335                    if (str.length()>0) { 
     336                        tgt[i].add(str); 
     337                    } 
     338                } 
     339 
    412340            } 
    413  
    414             attributes.put(parts[0], new Attribute(parts[0],displayName)); 
    415         } 
    416  
    417         is.close(); 
    418         reader.close(); 
    419         reader = null; 
    420         is = null; 
    421  
    422         this.mapDsAttrs.put(datasetName, attributes); 
    423  
    424         return attributes; 
    425     } 
    426  
    427     /** 
    428      * Get filter. 
    429      * @param datasetName dataset name 
    430      * @param filterName filter name 
    431      * @return filter 
    432      */ 
    433     public Filter getFilter(String datasetName, String filterName) { 
    434         if (datasetName==null || filterName==null) { 
    435             throw new java.lang.IllegalArgumentException("datasetName and filterName cannot be null"); 
    436         } 
    437  
    438         Map<String, Filter> map = this.mapDsFilters.get(datasetName); 
    439         if (map==null) { 
    440             return null; 
    441         } 
    442  
    443         return map.get(filterName); 
    444     } 
    445  
    446     /** 
    447      * get Attribute. 
    448      * @param datasetName dataset name 
    449      * @param attrName attribute name 
    450      * @return attribute 
    451      */ 
    452     public Attribute getAttribute(String datasetName, String attrName) { 
    453         if (datasetName==null || attrName==null) { 
    454             throw new java.lang.IllegalArgumentException("datasetName and attrName cannot be null"); 
    455         } 
    456  
    457         Map<String, Attribute> map = this.mapDsAttrs.get(datasetName); 
    458         if (map==null) { 
    459             return null; 
    460         } 
    461  
    462         return map.get(attrName); 
    463     } 
    464  
    465     /** 
    466      * Send the XML query to Biomart, and get the result as table. 
    467      * @param xmlQuery query xml 
    468      * @return result {@link BufferedReader} 
    469      * @throws IOException if failed to read 
    470      */ 
    471     public BufferedReader sendQuery(String xmlQuery) throws IOException { 
    472  
    473         //System.out.println("=======Query = " + xmlQuery); 
    474  
    475         URL url = new URL(baseURL); 
    476         URLConnection uc = url.openConnection(); 
    477         uc.setDoOutput(true); 
    478         uc.setRequestProperty("User-Agent", "Java URLConnection"); 
    479  
    480         OutputStream os = uc.getOutputStream(); 
    481  
    482         final String postStr = "query=" + xmlQuery; 
    483         PrintStream ps = new PrintStream(os); 
    484  
    485         // Post the data 
    486         ps.print(postStr); 
    487         os.close(); 
    488         ps.close(); 
    489         ps = null; 
    490         os = null; 
    491  
    492         return new BufferedReader(new InputStreamReader(uc.getInputStream()), BUFFER_SIZE); 
    493     } 
    494  
    495     /** 
    496      * get Database/mart. 
    497      * @param dbname database name 
    498      * @return database 
    499      */ 
    500     public Database getDatabase(final String dbname) { 
    501         return databases.get(dbname); 
    502     } 
    503  
    504     /** 
    505      * get Dataset. 
    506      * @param dsname dataset name 
    507      * @return dataset 
    508      */ 
    509     public Dataset getDataset(final String dsname) { 
    510         return datasets.get(dsname); 
    511     } 
    512      
    513     private static final int msConnectionTimeout = 2000; 
    514     //TODO: test when IOException is throwed 
    515     protected static InputStream getInputStream(URL source) throws IOException { 
    516         InputStream stream = null; 
    517         int expCount = 0; 
    518         int timeOut = msConnectionTimeout; 
    519         while (true) { // multiple chances 
    520             try { 
    521                 URLConnection uc = source.openConnection(); 
    522                 uc.setUseCaches(false); // don't use a cached page 
    523                 uc.setConnectTimeout(timeOut); // set timeout for connection 
    524                 stream = uc.getInputStream(); 
    525                 break; 
    526             } catch (IOException e) { 
    527                 if (expCount++==4) { 
    528                     throw(e); 
    529                 } else { 
    530                     timeOut *= 2; 
    531                 } 
    532             } 
    533         } 
    534  
    535         return stream; 
     341        } catch (IOException e) { 
     342            throw new IDMapperException(e); 
     343        } 
     344 
     345        return result; 
    536346    } 
    537347}