http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-biomart-martservice/pom.xml 
b/taverna-biomart-martservice/pom.xml
new file mode 100644
index 0000000..582a601
--- /dev/null
+++ b/taverna-biomart-martservice/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>net.sf.taverna</groupId>
+               <artifactId>taverna-parent</artifactId>
+               <version>3.0.1-SNAPSHOT</version>
+       </parent>
+       <groupId>org.biomart</groupId>
+       <artifactId>martservice</artifactId>
+       <packaging>bundle</packaging>
+       <name>MartService</name>
+       <version>2.0.1-SNAPSHOT</version>
+       <description>Biomart webservice API</description>
+       
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <version>2.3.7</version>
+                               <extensions>true</extensions>
+                               <configuration>
+                                       <instructions>
+                                               
<Private-Package>org.ensembl.mart.lib,org.ensembl.mart.lib.config,org.ensembl.mart.util</Private-Package>
+                                               
<Import-Package>!org.ensembl.util,!org.ensembl.mart.editor,!oracle.sql,!gnu.getopt,!org.ewin.*,*</Import-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       
+       <dependencies>
+               <dependency>
+                       <groupId>org.biomart</groupId>
+                       <artifactId>martj</artifactId>
+                       <version>0.6</version>
+                       <scope>provided</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.jdom</groupId>
+                       <artifactId>com.springsource.org.jdom</artifactId>
+                       <version>1.1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       
<artifactId>com.springsource.org.apache.commons.httpclient</artifactId>
+                       <version>3.1.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.commons</groupId>
+                       
<artifactId>com.springsource.org.apache.commons.io</artifactId>
+                       <version>1.4.0</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.log4j</groupId>
+                       
<artifactId>com.springsource.org.apache.log4j</artifactId>
+                       <version>${log4j.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>junit</groupId>
+                       <artifactId>junit</artifactId>
+                       <version>${junit.version}</version>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+
+       <repositories>
+               <repository>
+                       <releases />
+                       <snapshots>
+                               <enabled>false</enabled>
+                       </snapshots>
+                       <id>mygrid-repository</id>
+                       <name>myGrid Repository</name>
+                       <url>http://www.mygrid.org.uk/maven/repository</url>
+               </repository>
+               <repository>
+                       <releases>
+                               <enabled>false</enabled>
+                       </releases>
+                       <snapshots />
+                       <id>mygrid-snapshot-repository</id>
+                       <name>myGrid Snapshot Repository</name>
+                       
<url>http://www.mygrid.org.uk/maven/snapshot-repository</url>
+               </repository>
+               <repository>
+                       <id>com.springsource.repository.bundles.release</id>
+                       <name>SpringSource Enterprise Bundle Repository - 
SpringSource Bundle Releases</name>
+                       
<url>http://repository.springsource.com/maven/bundles/release</url>
+               </repository>
+               <repository>
+                       <id>com.springsource.repository.bundles.external</id>
+                       <name>SpringSource Enterprise Bundle Repository - 
External Bundle Releases</name>
+                       
<url>http://repository.springsource.com/maven/bundles/external</url>
+               </repository>
+       </repositories>
+       <scm>
+               
<connection>scm:git:https://github.com/taverna/taverna-biomart-martservice.git</connection>
+               
<developerConnection>scm:git:ssh://g...@github.com:taverna/taverna-biomart-martservice.git</developerConnection>
+               
<url>https://github.com/taverna/taverna-biomart-martservice/</url>
+               <tag>HEAD</tag>
+       </scm>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/DatasetLink.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/DatasetLink.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/DatasetLink.java
new file mode 100644
index 0000000..e5dccd4
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/DatasetLink.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: DatasetLink.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2007/12/13 11:38:55 $
+ *               by   $Author: davidwithers $
+ * Created on 12-Apr-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The link between two MartDatasets and the list of possible the link IDs that
+ * could join the source and target MartDataset.
+ * 
+ * @author David Withers
+ */
+public class DatasetLink {
+       private static final Comparator<DatasetLink> displayComparator = new 
DatasetLinkComparator();
+
+       private MartDataset sourceDataset;
+
+       private MartDataset targetDataset;
+
+       private Set<String> links = new HashSet<String>();
+
+       /**
+        * Constructs an instance of an <code>DatasetLink</code> with the
+        * specified source and target.
+        * 
+        * @param sourceDataset
+        *            the link source
+        * @param targetDataset
+        *            the link target
+        */
+       public DatasetLink(MartDataset sourceDataset, MartDataset 
targetDataset) {
+               this.sourceDataset = sourceDataset;
+               this.targetDataset = targetDataset;
+       }
+
+       /**
+        * Returns the source Dataset.
+        * 
+        * @return the source Dataset
+        */
+       public MartDataset getSourceDataset() {
+               return sourceDataset;
+       }
+
+       /**
+        * Sets the source Dataset.
+        * 
+        * @param sourceDataset
+        *            the sourceDataset to set
+        */
+       public void setSourceDataset(MartDataset sourceDataset) {
+               this.sourceDataset = sourceDataset;
+       }
+
+       /**
+        * Returns the target Dataset.
+        * 
+        * @return the target Dataset
+        */
+       public MartDataset getTargetDataset() {
+               return targetDataset;
+       }
+
+       /**
+        * Sets the target Dataset.
+        * 
+        * @param targetDataset
+        *            the target Dataset to set
+        */
+       public void setTargetDataset(MartDataset targetDataset) {
+               this.targetDataset = targetDataset;
+       }
+
+       /**
+        * Returns the link IDs that could join the source and target 
MartDatasets.
+        * 
+        * @return the link IDs that could join the source and target 
MartDatasets
+        */
+       public String[] getLinks() {
+               return links.toArray(new String[links.size()]);
+       }
+
+       /**
+        * Adds a link ID.
+        * 
+        * @param link
+        *            the link ID to add.
+        */
+       public void addLink(String link) {
+               links.add(link);
+       }
+
+       /**
+        * Returns true if this DatasetLink has link IDs.
+        * 
+        * @return true if this DatasetLink has link IDs
+        */
+       public boolean hasLinks() {
+               return !links.isEmpty();
+       }
+
+       public String toString() {
+               return "[" + 
sourceDataset.getMartURLLocation().getDisplayName() + "] "
+                               + sourceDataset.getDisplayName();
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#hashCode()
+        */
+       public int hashCode() {
+               final int PRIME = 31;
+               int result = 1;
+               result = PRIME * result + ((sourceDataset == null) ? 0 : 
sourceDataset.hashCode());
+               result = PRIME * result + ((targetDataset == null) ? 0 : 
targetDataset.hashCode());
+               return result;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               final DatasetLink other = (DatasetLink) obj;
+               if (sourceDataset == null) {
+                       if (other.sourceDataset != null)
+                               return false;
+               } else if (!sourceDataset.equals(other.sourceDataset))
+                       return false;
+               if (targetDataset == null) {
+                       if (other.targetDataset != null)
+                               return false;
+               } else if (!targetDataset.equals(other.targetDataset))
+                       return false;
+               return true;
+       }
+
+       /**
+        * Returns a Comparator that compares DatasetLinks based on the display 
name
+        * of the source dataset and the display name of the MartURLLocation
+        * containing the source dataset.
+        * 
+        * @return the display comparator
+        */
+       public static Comparator<DatasetLink> getDisplayComparator() {
+               return displayComparator;
+       }
+
+}
+
+/**
+ * Comparator that compares DatasetLinks based on the display name of the 
source
+ * MartDataset and the display name of the MartURLLocation containing the 
source
+ * MartDataset.
+ * 
+ * @author David Withers
+ */
+class DatasetLinkComparator implements Comparator<DatasetLink> {
+
+       /**
+        * Compares two DatasetLinks based on the display name of the source 
dataset
+        * and the display name of the MartURLLocation containing the source
+        * dataset.
+        * 
+        * @param o1
+        *            the first DatasetLink to be compared
+        * @param o2
+        *            the second DatasetLink to be compared
+        * @return a negative integer, zero, or a positive integer as the first
+        *         argument is less than, equal to, or greater than the second
+        */
+       public int compare(DatasetLink o1, DatasetLink o2) {
+               MartDataset ds1 = o1.getSourceDataset();
+               MartDataset ds2 = o2.getSourceDataset();
+               int result = 
ds1.getDisplayName().compareTo(ds2.getDisplayName());
+               if (result == 0) {
+                       result = 
ds1.getMartURLLocation().getDisplayName().compareTo(
+                                       
ds2.getMartURLLocation().getDisplayName());
+               }
+               return result;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartDataset.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartDataset.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartDataset.java
new file mode 100644
index 0000000..8c0f584
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartDataset.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartDataset.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2007/10/04 14:17:19 $
+ *               by   $Author: davidwithers $
+ * Created on 17-Mar-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.util.Comparator;
+
+/**
+ * The dataset returned by a BioMart web service.
+ * 
+ * @author David Withers
+ */
+public class MartDataset {
+       private static final Comparator<MartDataset> displayComparator = new 
MartDatasetComparator();
+
+       private String type;
+
+       private String name;
+
+       private String displayName;
+
+       private boolean visible;
+
+       private long initialBatchSize;
+
+       private long maximumBatchSize;
+
+       private String interfaceValue;
+
+       private String modified;
+
+       private MartURLLocation martURLLocation;
+
+       /**
+        * Returns the displayName.
+        * 
+        * @return the displayName.
+        */
+       public String getDisplayName() {
+               return displayName;
+       }
+
+       /**
+        * Sets the displayName.
+        * 
+        * @param displayName
+        *            the displayName to set.
+        */
+       public void setDisplayName(String displayName) {
+               this.displayName = displayName;
+       }
+
+       /**
+        * Returns the initialBatchSize.
+        * 
+        * @return the initialBatchSize.
+        */
+       public long getInitialBatchSize() {
+               return initialBatchSize;
+       }
+
+       /**
+        * Sets the initialBatchSize.
+        * 
+        * @param initialBatchSize
+        *            the initialBatchSize to set.
+        */
+       public void setInitialBatchSize(long initialBatchSize) {
+               this.initialBatchSize = initialBatchSize;
+       }
+
+       /**
+        * Returns the maximumBatchSize.
+        * 
+        * @return the maximumBatchSize.
+        */
+       public long getMaximumBatchSize() {
+               return maximumBatchSize;
+       }
+
+       /**
+        * Sets the maximumBatchSize.
+        * 
+        * @param maximumBatchSize
+        *            the maximumBatchSize to set.
+        */
+       public void setMaximumBatchSize(long maximumBatchSize) {
+               this.maximumBatchSize = maximumBatchSize;
+       }
+
+       /**
+        * Returns the name.
+        * 
+        * @return the name.
+        */
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * Sets the name.
+        * 
+        * @param name
+        *            the name to set.
+        */
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       /**
+        * Returns the type.
+        * 
+        * @return the type.
+        */
+       public String getType() {
+               return type;
+       }
+
+       /**
+        * Sets the type.
+        * 
+        * @param type
+        *            the type to set.
+        */
+       public void setType(String type) {
+               this.type = type;
+       }
+
+       /**
+        * Returns the visible flag.
+        * 
+        * @return the visible flag
+        */
+       public boolean isVisible() {
+               return visible;
+       }
+
+       /**
+        * Sets the visible flag.
+        * 
+        * @param visible
+        *            the visible flag
+        */
+       public void setVisible(boolean visible) {
+               this.visible = visible;
+       }
+
+       /**
+        * Returns the modified date.
+        *
+        * @return the modified date
+        */
+       public String getModified() {
+               return modified;
+       }
+
+       /**
+        * Sets the modified date.
+        *
+        * @param modified the new modified date
+        */
+       public void setModified(String modified) {
+               this.modified = modified;
+       }
+
+       /**
+        * Returns the interface.
+        *
+        * @return the interface
+        */
+       public String getInterface() {
+               return interfaceValue;
+       }
+
+       /**
+        * Sets the interface.
+        *
+        * @param interfaceValue the new interface
+        */
+       public void setInterface(String interfaceValue) {
+               this.interfaceValue = interfaceValue;
+       }
+
+       /**
+        * Returns the martURLLocation.
+        * 
+        * @return the martURLLocation
+        */
+       public MartURLLocation getMartURLLocation() {
+               return martURLLocation;
+       }
+
+       /**
+        * Sets the martURLLocation.
+        * 
+        * @param martURLLocation
+        *            the martURLLocation to set.
+        */
+       public void setMartURLLocation(MartURLLocation martURLLocation) {
+               this.martURLLocation = martURLLocation;
+       }
+
+       /**
+        * Returns the virtualSchema of the martURLLocation. If the 
martURLLocation
+        * is null, null is returned.
+        * 
+        * @return the virtualSchema of the martURLLocation
+        */
+       public String getVirtualSchema() {
+               MartURLLocation martURLLocation = getMartURLLocation();
+               if (martURLLocation != null) {
+                       return martURLLocation.getVirtualSchema();
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Returns the qualified name of this dataset in the format
+        * 'virtualSchemaName.datasetName'. If there is no virtualSchema the
+        * datasetName is returned.
+        * 
+        * @return the qualified name of this dataset
+        */
+       public String getQualifiedName() {
+               String schema = getVirtualSchema();
+               if (schema != null) {
+                       return schema + "." + getName();
+               } else {
+                       return getName();
+               }
+       }
+
+       /**
+        * Returns the display name.
+        * 
+        * @return the display name
+        */
+       public String toString() {
+               return getDisplayName();
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#hashCode()
+        */
+       public int hashCode() {
+               final int PRIME = 31;
+               int result = 1;
+               result = PRIME
+                               * result
+                               + ((getQualifiedName() == null) ? 0 : 
getQualifiedName()
+                                               .hashCode());
+               return result;
+       }
+
+       /**
+        * Tests equality based on the qualified name.
+        * 
+        * @return true if the objects are equal based on the qualified name
+        */
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               final MartDataset other = (MartDataset) obj;
+               if (getQualifiedName() == null) {
+                       if (other.getQualifiedName() != null)
+                               return false;
+               } else if (!getQualifiedName().equals(other.getQualifiedName()))
+                       return false;
+               return true;
+       }
+
+       /**
+        * Returns a Comparator that compares MartDatasets based on their 
display
+        * names.
+        * 
+        * @return the display comparator
+        */
+       public static Comparator<MartDataset> getDisplayComparator() {
+               return displayComparator;
+       }
+
+}
+
+/**
+ * Comparator that compares MartDatasets based on their display names.
+ * 
+ * @author David Withers
+ */
+class MartDatasetComparator implements Comparator<MartDataset> {
+
+       /**
+        * Compares two MartDatasets based on their display names.
+        * 
+        * @param martDataset1
+        *            the first MartDataset to be compared
+        * @param martDataset2
+        *            the second MartDataset to be compared
+        * @return a negative integer, zero, or a positive integer as the first
+        *         argument is less than, equal to, or greater than the second
+        */
+       public int compare(MartDataset martDataset1, MartDataset martDataset2) {
+               return 
martDataset1.getDisplayName().compareTo(martDataset2.getDisplayName());
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartQuery.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartQuery.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartQuery.java
new file mode 100644
index 0000000..9f75566
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartQuery.java
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartQuery.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2007/12/13 11:38:55 $
+ *               by   $Author: davidwithers $
+ * Created on 08-May-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.biomart.martservice.query.Attribute;
+import org.biomart.martservice.query.Dataset;
+import org.biomart.martservice.query.Filter;
+import org.biomart.martservice.query.Link;
+import org.biomart.martservice.query.Query;
+import org.ensembl.mart.lib.config.AttributeDescription;
+import org.ensembl.mart.lib.config.DatasetConfig;
+
+/**
+ * Class for creating queries to send to a BioMart web service.
+ * 
+ * @author David Withers
+ */
+public class MartQuery {
+       private MartService martService;
+
+       private MartDataset martDataset;
+
+       private Query query;
+
+       private Map<String, String> linkedDatasets = new HashMap<String, 
String>();
+
+       private String softwareVersion;
+
+       public MartQuery() {
+
+       }
+
+       public MartQuery(MartService martService, MartDataset martDataset, 
String requestId) {
+               String version = null;
+               try {
+                       version = 
martService.getVersion(martDataset.getMartURLLocation());
+               } catch (MartServiceException e) {
+                       //assume it's a pre 0.5 mart service
+               }
+               setMartService(martService);
+               setMartDataset(martDataset);
+               if (version == null || version.equals("0.4")) {
+                       setQuery(new Query(martDataset.getVirtualSchema(), 
null, requestId));
+               } else {
+                       setQuery(new Query(martDataset.getVirtualSchema(), 
version, requestId));
+               }
+       }
+
+       /**
+        * @param martService
+        * @param martDataset
+        * @param query
+        */
+       public MartQuery(MartService martService, MartDataset martDataset,
+                       Query query) {
+               setMartService(martService);
+               setMartDataset(martDataset);
+               setQuery(query);
+       }
+
+       /**
+        * Returns the martDataset.
+        * 
+        * @return the martDataset.
+        */
+       public MartDataset getMartDataset() {
+               return martDataset;
+       }
+
+       /**
+        * Sets the martDataset.
+        * 
+        * @param martDataset
+        *            the martDataset to set.
+        */
+       public void setMartDataset(MartDataset martDataset) {
+               this.martDataset = martDataset;
+       }
+
+       /**
+        * Returns the martService.
+        * 
+        * @return the martService.
+        */
+       public MartService getMartService() {
+               return martService;
+       }
+
+       /**
+        * Sets the martService.
+        * 
+        * @param martService
+        *            the martService to set.
+        */
+       public void setMartService(MartService martService) {
+               this.martService = martService;
+       }
+
+       /**
+        * Returns the query.
+        * 
+        * @return the query.
+        */
+       public Query getQuery() {
+               return query;
+       }
+
+       /**
+        * Sets the query.
+        * 
+        * @param query
+        *            the query to set.
+        */
+       public void setQuery(Query query) {
+               this.query = query;
+               softwareVersion = query.getSoftwareVersion();
+       }
+
+       /**
+        * Adds the ID that links the specified dataset to the initial dataset.
+        * 
+        * @param datasetName
+        *            the dataset
+        * @param linkId
+        *            the link ID
+        */
+       public void addLinkedDataset(String datasetName, String linkId) {
+               linkedDatasets.put(datasetName, linkId);
+       }
+
+       /**
+        * Removes a dataset and any datasets linked to it.
+        * 
+        * @param datasetName
+        *            the dataset to remove
+        */
+       public void removeLinkedDataset(String datasetName) {
+               linkedDatasets.remove(datasetName);
+               if (query.containsDataset(datasetName)) {
+                       Dataset dataset = query.getDataset(datasetName);
+                       dataset.removeAllAttributes();
+                       dataset.removeAllFilters();
+                       query.removeDataset(dataset);
+                       for (Link link : query.getLinks(datasetName)) {
+                               removeLinkedDataset(link.getTarget());
+                       }
+
+               }
+               if (query.containsLink(datasetName)) {
+                       query.removeLink(query.getLink(datasetName));
+               }
+       }
+
+       /**
+        * Changes the ID that links a dataset. This method performs no 
function,
+        * nor does it throw an exception, if the specified dataset does not 
exist.
+        * 
+        * @param datasetName
+        *            the dataset
+        * @param linkId
+        *            the link ID
+        */
+       public void changeLinkedDataset(String datasetName, String linkId) {
+               if (linkedDatasets.containsKey(datasetName)) {
+                       linkedDatasets.put(datasetName, linkId);
+                       if (query.containsLink(datasetName)) {
+                               
query.getLink(datasetName).setDefaultLink(linkId);
+                       }
+               }
+       }
+
+       public Set<String> getLinkedDatasets() {
+               return linkedDatasets.keySet();
+       }
+
+       public String getLink(String datasetName) {
+               return (String) linkedDatasets.get(datasetName);
+       }
+
+       /**
+        * Returns the Datasets that this Query contains in the order specified 
by
+        * the links.
+        * 
+        * @return the Datasets that this Query contains in the order specified 
by
+        *         the links
+        */
+       public List<Dataset> getDatasetsInLinkOrder() {
+               if (query.getLinks().size() > 0) {
+                       List<Dataset> datasets = new ArrayList<Dataset>();
+                       
datasets.addAll(getLinkedDatasets(martDataset.getName()));
+                       // add other datasets
+                       for (Dataset dataset : query.getDatasets()) {
+                               if (!datasets.contains(dataset)) {
+                                       datasets.add(dataset);
+                               }
+                       }
+                       return datasets;
+               } else {
+                       return query.getDatasets();
+               }
+       }
+
+       /**
+        * @param dataset
+        * @return
+        */
+       private List<Dataset> getLinkedDatasets(String dataset) {
+               List<Dataset> datasets = new ArrayList<Dataset>();
+               datasets.add(query.getDataset(dataset));
+               if (query.containsLink(dataset)) {
+                       Link link = query.getLink(dataset);
+                       if (!link.getTarget().equals(martDataset.getName())) {
+                               
datasets.addAll(getLinkedDatasets(link.getTarget()));
+                       }
+               }
+               return datasets;
+       }
+
+       /**
+        * Returns all the Attributes from all the Datasets in this Query in the
+        * order specified by the links.
+        * 
+        * @return all the Attributes from all the Datasets in this Query in the
+        *         order specified by the links
+        */
+       public List<Attribute> getAttributesInLinkOrder() {
+               List<Attribute> attributes = new ArrayList<Attribute>();
+               List<Dataset> datasets;
+               if (softwareVersion == null) {
+                       datasets = getDatasetsInLinkOrder();
+               } else {
+                       datasets = query.getDatasets();
+               }
+               for (Dataset dataset : datasets) {
+                       attributes.addAll(dataset.getAttributes());
+               }
+               return attributes;
+       }
+
+       /**
+        * Adds an Attribute to the Dataset with the given datasetName. If the 
Query
+        * has no Dataset with the given datasetName then a new Dataset is 
created.
+        * 
+        * @param datasetName
+        *            the name of the Dataset to add the Attribute to
+        * @param attribute
+        *            the Attribute to add
+        * @throws MartServiceException
+        */
+       public void addAttribute(String datasetName, Attribute attribute) {
+               if (!query.containsDataset(datasetName)) {
+                       Dataset dataset = new Dataset(datasetName);
+                       if (datasetName.equals(martDataset.getName())) {
+                               query.addDataset(0, dataset);
+                       } else {
+                               query.addDataset(dataset);
+                       }
+               }
+               Dataset dataset = query.getDataset(datasetName);
+               dataset.addAttribute(attribute);
+       }
+
+       /**
+        * Removes an Attribute from its containing Dataset.
+        * 
+        * @param attribute
+        */
+       public void removeAttribute(Attribute attribute) {
+               Dataset dataset = attribute.getContainingDataset();
+               if (dataset != null) {
+                       if (dataset.removeAttribute(attribute)) {
+                               if (!dataset.hasAttributes() && 
!dataset.hasFilters()) {
+                                       Query query = 
dataset.getContainingQuery();
+                                       if (query != null) {
+                                               query.removeDataset(dataset);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Adds a Filter to the Dataset with the given datasetName. If the 
Query has
+        * no Dataset with the given datasetName then a new Dataset is created.
+        * 
+        * @param datasetName
+        *            the name of the Dataset to add the Filter to
+        * @param filter
+        *            the Filter to add
+        * @throws MartServiceException
+        */
+       public void addFilter(String datasetName, Filter filter) {
+               if (!query.containsDataset(datasetName)) {
+                       Dataset dataset = new Dataset(datasetName);
+                       if (datasetName.equals(martDataset.getName())) {
+                               query.addDataset(0, dataset);
+                       } else {
+                               query.addDataset(dataset);
+                       }
+               }
+               Dataset dataset = query.getDataset(datasetName);
+               dataset.addFilter(filter);
+       }
+
+       /**
+        * Removes a Filter from its containing Dataset.
+        * 
+        * @param filter
+        */
+       public void removeFilter(Filter filter) {
+               Dataset dataset = filter.getContainingDataset();
+               if (dataset != null) {
+                       if (dataset.removeFilter(filter)) {
+                               if (!dataset.hasAttributes() && 
!dataset.hasFilters()) {
+                                       Query query = 
dataset.getContainingQuery();
+                                       if (query != null) {
+                                               query.removeDataset(dataset);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @throws MartServiceException
+        */
+       public void calculateLinks() throws MartServiceException {
+               if (softwareVersion == null) {
+                       if (!martService.linksCalculated()) {
+                               martService.calculateLinks();
+                       }
+                       for (Link link : query.getLinks()) {
+                               query.removeLink(link);
+                       }
+                       for (Dataset dataset : query.getDatasets()) {
+                               if 
(!martDataset.getName().equals(dataset.getName())) {
+                                       addLinks(dataset.getName());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * @param source
+        * @throws MartServiceException
+        */
+       public void addLinks(String source) throws MartServiceException {
+               MartDataset sourceDataset = martService.getDataset(martDataset
+                               .getVirtualSchema(), source);
+               MartDataset targetDataset = martDataset;
+               List<MartDataset> path = martService.getPath(sourceDataset, 
targetDataset);
+               if (path == null) {
+                       path = martService.getPath(targetDataset, 
sourceDataset);
+               }
+               if (path == null) {
+                       throw new MartServiceException("No link between " + 
source
+                                       + " and " + targetDataset.getName());
+               }
+               Iterator<MartDataset> iter = path.iterator();
+               if (iter.hasNext()) {
+                       MartDataset lastDataset = (MartDataset) iter.next();
+                       while (iter.hasNext()) {
+                               MartDataset dataset = (MartDataset) iter.next();
+                               DatasetLink link = 
martService.getLinkBetween(lastDataset,
+                                               dataset);
+                               String linkId = link.getLinks()[0];
+                               if (link.getLinks().length > 1) {
+                                       if (getLink(source) != null) {
+                                               linkId = getLink(source);
+                                       } else {
+                                               List<Attribute> attributes = 
query.getDataset(source)
+                                                               
.getAttributes();
+                                               if (attributes.size() > 0) {
+                                                       Attribute attribute = 
(Attribute) attributes.get(0);
+                                                       DatasetConfig config = 
martService
+                                                                       
.getDatasetConfig(sourceDataset);
+                                                       if 
(config.containsAttributeDescription(attribute
+                                                                       
.getName())) {
+                                                               
AttributeDescription description = config
+                                                                               
.getAttributeDescriptionByInternalName(attribute
+                                                                               
                .getName());
+                                                               String 
datasetLink = description
+                                                                               
.getDatasetLink();
+                                                               if (datasetLink 
!= null) {
+                                                                       linkId 
= datasetLink;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               query.addLink(new Link(lastDataset.getName(),
+                                               dataset.getName(), linkId));
+                               lastDataset = dataset;
+                       }
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartRegistry.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartRegistry.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartRegistry.java
new file mode 100644
index 0000000..93bf04d
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartRegistry.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartRegistry.java,v $
+ * Revision           $Revision: 1.2 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2007/12/13 11:38:55 $
+ *               by   $Author: davidwithers $
+ * Created on 17-Mar-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The MartRegistry returned by a BioMart web service.
+ * 
+ * @author David Withers
+ */
+public class MartRegistry {
+       private List<MartURLLocation> martURLLocations = new 
ArrayList<MartURLLocation>();
+
+       /**
+        * Returns the martURLLocations.
+        * 
+        * @return the martURLLocations.
+        */
+       public MartURLLocation[] getMartURLLocations() {
+               return martURLLocations
+                               .toArray(new 
MartURLLocation[martURLLocations.size()]);
+       }
+
+       /**
+        * Adds a martURLLocation to the registry.
+        * 
+        * @param martURLLocations
+        *            the martURLLocations to add.
+        */
+       public void addMartURLLocation(MartURLLocation martURLLocation) {
+               martURLLocations.add(martURLLocation);
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#hashCode()
+        */
+       public int hashCode() {
+               final int PRIME = 31;
+               int result = 1;
+               result = PRIME * result + ((martURLLocations == null) ? 0 : 
martURLLocations.hashCode());
+               return result;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               final MartRegistry other = (MartRegistry) obj;
+               if (martURLLocations == null) {
+                       if (other.martURLLocations != null)
+                               return false;
+               } else if (!martURLLocations.equals(other.martURLLocations))
+                       return false;
+               return true;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartService.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartService.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartService.java
new file mode 100644
index 0000000..c02bbb5
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartService.java
@@ -0,0 +1,709 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartService.java,v $errors/failure.html
+ * Revision           $Revision: 1.7 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/08/11 12:48:29 $
+ *               by   $Author: davidwithers $
+ * Created on 17-Mar-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import org.apache.log4j.Logger;
+import org.biomart.martservice.query.Query;
+import org.ensembl.mart.lib.config.ConfigurationException;
+import org.ensembl.mart.lib.config.DatasetConfig;
+import org.ensembl.mart.lib.config.DatasetConfigXMLUtils;
+import org.ensembl.mart.lib.config.Exportable;
+import org.ensembl.mart.lib.config.Importable;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.xml.sax.InputSource;
+
+/**
+ * A class for interacting with a BioMart web service.
+ * 
+ * @author David Withers
+ */
+public class MartService {
+       private static Logger logger = Logger.getLogger(MartServiceUtils.class);
+
+       private String location;
+
+       private String requestId;
+
+       private File cacheDirectory;
+
+       private MartRegistry registry;
+
+       private Map<MartURLLocation, String> versionMap = new 
HashMap<MartURLLocation, String>();
+
+       private Map<String, MartDataset[]> datasetsMap = new HashMap<String, 
MartDataset[]>();
+
+       private Map<String, SoftReference<DatasetConfig>> datasetConfigMap = 
new HashMap<String, SoftReference<DatasetConfig>>();
+
+       private Map<String, Importable[]> importablesMap = new HashMap<String, 
Importable[]>();
+
+       private Map<String, Exportable[]> exportablesMap = new HashMap<String, 
Exportable[]>();
+
+       private Map<MartDataset, List<DatasetLink>> linkableDatasetsMap = new 
HashMap<MartDataset, List<DatasetLink>>();
+
+       private Map<MartDataset, Set<DatasetLink>> datasetToLinkSetMap = new 
HashMap<MartDataset, Set<DatasetLink>>();
+
+       private Map<MartDataset, Map<MartDataset, MartDataset>> 
datasetsToPathMap = new HashMap<MartDataset, Map<MartDataset, MartDataset>>();
+
+       private static final Map<String, MartService> martServiceMap = new 
HashMap<String, MartService>();
+
+       private static final String fs = System.getProperty("file.separator");
+
+       private boolean linksCalculated = false;
+
+       /**
+        * Constructs an instance of a <code>MartService</code> with the 
specified
+        * location.
+        * 
+        * The location must be the URL of a valid BioMart MartService, e.g.
+        * http://www.biomart.org/biomart/martservice
+        * 
+        * @param location
+        *            the URL of the MartService
+        */
+       private MartService(String location) {
+               this.location = location;
+       }
+
+       /**
+        * Returns a <code>MartService</code> for the specified location. If a
+        * <code>MartService</code> does not exist for the location a new one is
+        * constructed.
+        * 
+        * The location must be the URL of a valid BioMart MartService, e.g.
+        * http://www.biomart.org/biomart/martservice
+        * 
+        * @param location
+        *            the URL of the MartService
+        */
+       public static MartService getMartService(String location) {
+               if (!martServiceMap.containsKey(location)) {
+                       martServiceMap.put(location, new MartService(location));
+               }
+               return martServiceMap.get(location);
+       }
+
+       /**
+        * Returns the requestId.
+        * 
+        * @return the requestId
+        */
+       public String getRequestId() {
+               return requestId;
+       }
+
+       /**
+        * Sets the requestId.
+        * 
+        * @param requestId
+        *            the new requestId
+        */
+       public void setRequestId(String requestId) {
+               this.requestId = requestId;
+       }
+
+       /**
+        * Returns the cacheDirectory.
+        * 
+        * @return the cacheDirectory
+        */
+       public File getCacheDirectory() {
+               return cacheDirectory;
+       }
+
+       /**
+        * Sets the cacheDirectory.
+        * 
+        * @param cacheDirectory
+        *            the new cacheDirectory
+        */
+       public void setCacheDirectory(File cacheDirectory) {
+               this.cacheDirectory = cacheDirectory;
+       }
+
+       /**
+        * Returns the URL of the MartService.
+        * 
+        * @return the URL of the MartService
+        */
+       public String getLocation() {
+               return location;
+       }
+
+       /**
+        * Removes any cached items.
+        */
+       public void clearCache() {
+               registry = null;
+               datasetsMap.clear();
+               datasetConfigMap.clear();
+               importablesMap.clear();
+               exportablesMap.clear();
+       }
+
+       /**
+        * Returns the MartRegistry for this MartService.
+        * 
+        * @return the MartRegistry for this MartService
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public MartRegistry getRegistry() throws MartServiceException {
+               if (registry == null) {
+                       registry = MartServiceUtils.getRegistry(location, 
requestId);
+               }
+               return registry;
+       }
+
+       public String getVersion(MartURLLocation martURLLocation)
+                       throws MartServiceException {
+               if (!versionMap.containsKey(martURLLocation)) {
+                       versionMap.put(martURLLocation, 
MartServiceUtils.getVersion(
+                                       location, requestId, martURLLocation));
+               }
+               return versionMap.get(martURLLocation);
+       }
+
+       /**
+        * Returns all the datasets available from this MartService.
+        * 
+        * @return all the datasets available from this MartService.
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public MartDataset[] getDatasets() throws MartServiceException {
+               List<MartDataset> datasets = new ArrayList<MartDataset>();
+               MartURLLocation[] locations = 
getRegistry().getMartURLLocations();
+               for (int i = 0; i < locations.length; i++) {
+                       
datasets.addAll(Arrays.asList(getDatasets(locations[i])));
+               }
+               return datasets.toArray(new MartDataset[datasets.size()]);
+       }
+
+       /**
+        * Returns the datasets belonging to the virtualSchema.
+        * 
+        * @param virtualSchema
+        *            the virtual schema to include datasets from.
+        * @return the datasets belonging to the virtualSchema.
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public MartDataset[] getDatasets(String virtualSchema)
+                       throws MartServiceException {
+               List<MartDataset> datasets = new ArrayList<MartDataset>();
+               MartURLLocation[] locations = 
getRegistry().getMartURLLocations();
+               for (int i = 0; i < locations.length; i++) {
+                       if (virtualSchema == null
+                                       || 
virtualSchema.equals(locations[i].getVirtualSchema())) {
+                               
datasets.addAll(Arrays.asList(getDatasets(locations[i])));
+                       }
+               }
+               return datasets.toArray(new MartDataset[datasets.size()]);
+       }
+
+       /**
+        * Returns the datasets specified by martURLLocation.
+        * 
+        * @param martURLLocation
+        *            where to find the datasets.
+        * @return the datasets specified by martURLLocation.
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public MartDataset[] getDatasets(MartURLLocation martURLLocation)
+                       throws MartServiceException {
+               String name = martURLLocation.getName();
+               if (!datasetsMap.containsKey(name)) {
+                       datasetsMap.put(name, 
MartServiceUtils.getDatasets(location,
+                                       requestId, martURLLocation));
+               }
+               return datasetsMap.get(name);
+       }
+
+       /**
+        * Returns the dataset specified by a virtualSchema and a dataset name.
+        * 
+        * @param virtualSchema
+        *            the virtualSchema containing the dataset
+        * @param datasetName
+        *            the name of the dataset to return
+        * @return a dataset
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public MartDataset getDataset(String virtualSchema, String datasetName)
+                       throws MartServiceException {
+               MartDataset result = null;
+               MartDataset[] datasets = getDatasets(virtualSchema);
+               for (int i = 0; i < datasets.length; i++) {
+                       if (datasetName.equals(datasets[i].getName())) {
+                               result = datasets[i];
+                               break;
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Returns the configuration for a dataset.
+        * 
+        * @param dataset
+        *            the dataset to get the configuration for
+        * @return the configuration for a dataset
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public DatasetConfig getDatasetConfig(MartDataset dataset)
+                       throws MartServiceException {
+               String qualifiedName = dataset.getQualifiedName();
+               DatasetConfig datasetConfig;
+               if (!datasetConfigMap.containsKey(qualifiedName)) {
+                       if (dataset.getModified() != null && cacheDirectory != 
null) {
+                               datasetConfig = 
getDatasetConfigFromCache(dataset);
+                       } else {
+                               datasetConfig = 
MartServiceUtils.getDatasetConfig(location,
+                                               requestId, dataset);
+                       }
+                       datasetConfigMap.put(qualifiedName,
+                                       new 
SoftReference<DatasetConfig>(datasetConfig));
+               } else {
+                       datasetConfig = 
datasetConfigMap.get(qualifiedName).get();
+                       if (datasetConfig == null) {
+                               if (dataset.getModified() != null && 
cacheDirectory != null) {
+                                       datasetConfig = 
getDatasetConfigFromCache(dataset);
+                               } else {
+                                       datasetConfig = 
MartServiceUtils.getDatasetConfig(location,
+                                                       requestId, dataset);
+                               }
+                               datasetConfigMap.put(qualifiedName,
+                                               new 
SoftReference<DatasetConfig>(datasetConfig));
+                       }
+
+               }
+               return datasetConfig;
+       }
+
+       private DatasetConfig getDatasetConfigFromCache(MartDataset dataset)
+                       throws MartServiceException {
+               DatasetConfig datasetConfig = null;
+               MartURLLocation mart = dataset.getMartURLLocation();
+               String path = mart.getHost() + fs + mart.getName() + fs
+                               + mart.getVirtualSchema();
+               File martCacheDir = new File(cacheDirectory, path);
+               martCacheDir.mkdirs();
+               File cache = new File(martCacheDir, dataset.getName() + ".cfg");
+               DatasetConfigXMLUtils datasetConfigXMLUtils = new 
DatasetConfigXMLUtils(
+                               true);
+               if (cache.exists()) {
+                       try {
+                               SAXBuilder builder = new SAXBuilder();
+                               Document doc = builder.build(new InputSource(
+                                               new GZIPInputStream(new 
FileInputStream(cache))));
+
+                               // Document doc =
+                               // 
datasetConfigXMLUtils.getDocumentForXMLStream(new
+                               // FileInputStream(cache));
+
+                               datasetConfig = datasetConfigXMLUtils
+                                               
.getDatasetConfigForDocument(doc);
+                               
datasetConfigXMLUtils.loadDatasetConfigWithDocument(
+                                               datasetConfig, doc);
+                               if (!datasetConfig.getModified().trim().equals(
+                                               dataset.getModified().trim())) {
+                                       logger.info(" " + 
datasetConfig.getModified().trim()
+                                                       + " != " + 
dataset.getModified().trim());
+                                       logger.info("  Database: "
+                                                       + 
dataset.getMartURLLocation().getDatabase()
+                                                       + ", Dataset: " + 
dataset.getName());
+                                       datasetConfig = null;
+                               }
+                       } catch (IOException e) {
+                               logger.debug("error reading cache from " + 
cache.getPath(), e);
+                               datasetConfig = null;
+                       } catch (ConfigurationException e) {
+                               logger.debug("error parsing from " + 
cache.getPath(), e);
+                               datasetConfig = null;
+                       } catch (JDOMException e) {
+                               logger.debug("error parsing from " + 
cache.getPath(), e);
+                               datasetConfig = null;
+                       }
+               }
+               if (datasetConfig == null) {
+                       datasetConfig = 
MartServiceUtils.getDatasetConfig(location,
+                                       requestId, dataset);
+                       try {
+                               GZIPOutputStream zipOutputStream = new 
GZIPOutputStream(
+                                               new FileOutputStream(cache));
+                               
datasetConfigXMLUtils.writeDatasetConfigToOutputStream(
+                                               datasetConfig, zipOutputStream);
+                               zipOutputStream.flush();
+                               zipOutputStream.close();
+                       } catch (IOException e) {
+                               logger.debug("error writing cache to " + 
cache.getPath(), e);
+                       } catch (ConfigurationException e) {
+                               logger.debug("error writing cache to " + 
cache.getPath(), e);
+                       }
+               }
+               return datasetConfig;
+       }
+
+       /**
+        * Returns the importables for a dataset.
+        * 
+        * @param dataset
+        * @return the importables for a dataset
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public Importable[] getImportables(MartDataset dataset)
+                       throws MartServiceException {
+               String qualifiedName = dataset.getQualifiedName();
+               if (!importablesMap.containsKey(qualifiedName)) {
+                       try {
+                               importablesMap.put(qualifiedName, 
getDatasetConfig(dataset)
+                                               .getImportables());
+                       } catch (MartServiceException e) {
+                               return new Importable[0];
+                       }
+               }
+               return importablesMap.get(qualifiedName);
+       }
+
+       /**
+        * Returns the exportables for a dataset.
+        * 
+        * @param dataset
+        * @return the exportables for a dataset
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public Exportable[] getExportables(MartDataset dataset)
+                       throws MartServiceException {
+               String qualifiedName = dataset.getQualifiedName();
+               if (!exportablesMap.containsKey(qualifiedName)) {
+                       try {
+                               exportablesMap.put(qualifiedName, 
getDatasetConfig(dataset)
+                                               .getExportables());
+                       } catch (MartServiceException e) {
+                               return new Exportable[0];
+                       }
+               }
+               return exportablesMap.get(qualifiedName);
+       }
+
+       /**
+        * Sends a <code>Query</code> to the MartService and returns the results
+        * of executing the query.
+        * 
+        * The results are returned as an array of lists; one list for each
+        * attribute specified in the query.
+        * 
+        * @param query
+        *            the query to execute
+        * @return the results of executing the query
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        */
+       public Object[] executeQuery(Query query) throws MartServiceException {
+               // logger.info(MartServiceUtils.queryToXML(query));
+               return MartServiceUtils.getResults(location, requestId, query);
+       }
+
+       /**
+        * Sends a <code>Query</code> to the MartService and writes the results 
to
+        * the <code>ResultReceiver</code> as each line of the result stream is
+        * read.
+        * 
+        * @param query
+        * @param resultReceiver
+        * @throws MartServiceException
+        *             if the MartService returns an error or is unavailable
+        * @throws ResultReceiverException 
+        *             if the ResultReceiver cannot receive the result
+        * @see ResultReceiver
+        */
+       public void executeQuery(Query query, ResultReceiver resultReceiver)
+                       throws MartServiceException, ResultReceiverException {
+               MartServiceUtils.putResults(location, requestId, query, 
resultReceiver);
+       }
+
+       /**
+        * Returns a list of datasets that can be linked to the specified 
dataset.
+        * 
+        * @param martDataset
+        * @return datasets that can be linked to the specified dataset
+        * @throws MartServiceException
+        */
+       public List<DatasetLink> getLinkableDatasets(MartDataset martDataset)
+                       throws MartServiceException {
+               if (!linkableDatasetsMap.containsKey(martDataset)) {
+                       List<DatasetLink> linkableDatasets = new 
ArrayList<DatasetLink>();
+
+                       Set<String> importableSet = new HashSet<String>();
+                       Importable[] importables = getImportables(martDataset);
+                       for (int i = 0; i < importables.length; i++) {
+                               importableSet.add(importables[i].getLinkName());
+                       }
+
+                       MartDataset[] datasets = 
getDatasets(martDataset.getVirtualSchema());
+                       for (int j = 0; j < datasets.length; j++) {
+                               if (datasets[j].isVisible()
+                                               && 
!datasets[j].getName().equals(martDataset.getName())) {
+                                       DatasetLink datasetLink = new 
DatasetLink(datasets[j],
+                                                       martDataset);
+                                       Exportable[] exportables = 
getExportables(datasets[j]);
+                                       for (int k = 0; k < exportables.length; 
k++) {
+                                               String link = 
exportables[k].getLinkName();
+                                               if 
(importableSet.contains(link)) {
+                                                       
datasetLink.addLink(link);
+                                               }
+                                       }
+                                       if (datasetLink.hasLinks()) {
+                                               
linkableDatasets.add(datasetLink);
+                                       }
+                               }
+                       }
+                       linkableDatasetsMap.put(martDataset, linkableDatasets);
+               }
+
+               return linkableDatasetsMap.get(martDataset);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       public boolean equals(Object obj) {
+               boolean result = false;
+               if (obj != null) {
+                       MartService other = (MartService) obj;
+                       if (location == null) {
+                               result = other.location == null;
+                       } else {
+                               result = location.equals(other.location);
+                       }
+               }
+               return result;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see java.lang.Object#hashCode()
+        */
+       public int hashCode() {
+               return location.hashCode();
+       }
+
+       public boolean linksCalculated() {
+               return linksCalculated;
+       }
+
+       // java implementation of the perl stuff that calculates links.
+       // all this should go for the next version of biomart.
+
+       public void calculateLinks() throws MartServiceException {
+               synchronized (location) {
+                       if (!linksCalculated) {
+                               datasetToLinkSetMap.clear();
+                               datasetsToPathMap.clear();
+
+                               MartDataset[] allDatasets = getDatasets();
+                               for (int i = 0; i < allDatasets.length; i++) {
+                                       MartDataset[] datasets = 
getDatasets(allDatasets[i]
+                                                       .getVirtualSchema());
+                                       for (int j = 0; j < datasets.length; 
j++) {
+                                               if 
(!allDatasets[i].getName().equals(
+                                                               
datasets[j].getName())) {
+                                                       
linkDatasets(allDatasets[i], datasets[j]);
+                                               }
+                                       }
+                               }
+                               for (int i = 0; i < allDatasets.length; i++) {
+                                       datasetsToPathMap.put(allDatasets[i],
+                                                       
dijkstra(allDatasets[i]));
+                               }
+                               linksCalculated = true;
+                       }
+               }
+       }
+
+       public List<MartDataset> getPath(MartDataset source, MartDataset 
target) {
+               List<MartDataset> path = new ArrayList<MartDataset>();
+
+               Map<MartDataset, MartDataset> pathMap = 
datasetsToPathMap.get(source);
+
+               MartDataset currentDataset = target;
+
+               while (currentDataset != null) {
+                       path.add(0, currentDataset);
+                       currentDataset = (MartDataset) 
pathMap.get(currentDataset);
+               }
+
+               if (path.size() < 2 || !path.get(0).equals(source)
+                               || !path.get(path.size() - 1).equals(target)) {
+                       return null;
+               }
+
+               return path;
+       }
+
+       public DatasetLink getLinkBetween(MartDataset exportingDataset,
+                       MartDataset importingDataset) {
+               Set<DatasetLink> links = 
datasetToLinkSetMap.get(exportingDataset);
+               for (DatasetLink link : links) {
+                       MartDataset targetDataset = link.getTargetDataset();
+                       if (importingDataset.equals(targetDataset)) {
+                               return link;
+                       }
+               }
+
+               return null;
+       }
+
+       public List<DatasetLink> getLinksFrom(MartDataset dataset) {
+               List<DatasetLink> linksFrom = new ArrayList<DatasetLink>();
+               Set<DatasetLink> links = datasetToLinkSetMap.get(dataset);
+               if (links != null) {
+                       for (DatasetLink link : links) {
+                               if (link.getSourceDataset().equals(dataset)) {
+                                       linksFrom.add(link);
+                               }
+                       }
+               }
+               return linksFrom;
+       }
+
+       public void linkDatasets(MartDataset source, MartDataset target)
+                       throws MartServiceException {
+               DatasetLink datasetLink = new DatasetLink(source, target);
+               Importable[] importables = getImportables(target);
+               for (int i = 0; i < importables.length; i++) {
+                       Exportable[] exportables = getExportables(source);
+                       for (int j = 0; j < exportables.length; j++) {
+                               if (importables[i].getLinkName().equals(
+                                               exportables[j].getLinkName())) {
+                                       String importVersion = 
importables[i].getLinkVersion();
+                                       String exportVersion = 
exportables[j].getLinkVersion();
+                                       if (importVersion != null && 
exportVersion != null) {
+                                               if 
(importVersion.equals(exportVersion)) {
+                                                       
datasetLink.addLink(importables[i].getLinkName());
+                                               }
+                                       } else {
+                                               
datasetLink.addLink(importables[i].getLinkName());
+                                       }
+                               }
+                       }
+               }
+               if (datasetLink.hasLinks()) {
+                       if (!datasetToLinkSetMap.containsKey(source)) {
+                               datasetToLinkSetMap.put(source, new 
HashSet<DatasetLink>());
+                       }
+                       if (!datasetToLinkSetMap.containsKey(target)) {
+                               datasetToLinkSetMap.put(target, new 
HashSet<DatasetLink>());
+                       }
+                       datasetToLinkSetMap.get(source).add(datasetLink);
+                       datasetToLinkSetMap.get(target).add(datasetLink);
+               }
+       }
+
+       public Map<MartDataset, MartDataset> dijkstra(MartDataset dataset)
+                       throws MartServiceException {
+               Map<MartDataset, MartDataset> path = new HashMap<MartDataset, 
MartDataset>();
+               LinkedList<MartDataset> vertices = new 
LinkedList<MartDataset>(Arrays
+                               
.asList(getDatasets(dataset.getVirtualSchema())));
+               Map<MartDataset, Integer> dist = new HashMap<MartDataset, 
Integer>();
+               for (MartDataset vertex : vertices) {
+                       dist.put(vertex, new Integer(10000));
+               }
+
+               dist.put(dataset, new Integer(0));
+
+               while (vertices.size() > 0) {
+                       int min_vert_idx = 0;
+                       MartDataset min_vert = (MartDataset) 
vertices.get(min_vert_idx);
+                       int min_dist = ((Integer) 
dist.get(min_vert)).intValue();
+
+                       for (int vertex_idx = 0; vertex_idx < vertices.size(); 
vertex_idx++) {
+                               MartDataset vertex = (MartDataset) 
vertices.get(vertex_idx);
+                               if (((Integer) dist.get(vertex)).intValue() < 
min_dist) {
+                                       min_vert_idx = vertex_idx;
+                                       min_vert = vertex;
+                                       min_dist = ((Integer) 
dist.get(vertex)).intValue();
+                               }
+                       }
+
+                       if (min_dist == 10000) {
+                               // Exhausted a disjoint set of datasets.
+                               break;
+                       }
+
+                       vertices.remove(min_vert_idx);
+
+                       List<DatasetLink> edges = getLinksFrom(min_vert);
+                       for (DatasetLink edge : edges) {
+                               MartDataset vertex = edge.getTargetDataset();
+
+                               if (((Integer) dist.get(vertex)).intValue() > 
((Integer) dist
+                                               .get(min_vert)).intValue() + 1) 
{
+                                       dist.put(vertex, new Integer(((Integer) 
dist.get(min_vert))
+                                                       .intValue() + 1));
+                                       path.put(vertex, min_vert);
+                               }
+                       }
+               }
+
+               return path;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceException.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceException.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceException.java
new file mode 100644
index 0000000..f1f0639
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceException.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartServiceException.java,v $
+ * Revision           $Revision: 1.1 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2007/01/31 14:12:05 $
+ *               by   $Author: davidwithers $
+ * Created on 05-May-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+/**
+ * Thrown when a MartService is inaccessable or returns an error.
+ * 
+ * @author David Withers
+ */
+public class MartServiceException extends Exception {
+       private static final long serialVersionUID = 5535008907746588537L;
+
+       /**
+        * Constructs a new exception with no detail message.
+        * 
+        */
+       public MartServiceException() {
+               super();
+       }
+
+       /**
+        * Constructs a new exception with the specified detail message.
+        * 
+        * @param message
+        *            the detail message
+        * @param cause
+        *            the cause (a null value is permitted, and indicates that 
the
+        *            cause is nonexistent or unknown)
+        */
+       public MartServiceException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+       /**
+        * Constructs a new exception with the specified detail message and 
cause.
+        * 
+        * @param message
+        *            the detail message
+        */
+       public MartServiceException(String message) {
+               super(message);
+       }
+
+       /**
+        * Constructs a new exception with the specified cause.
+        * 
+        * @param cause
+        *            the cause (a null value is permitted, and indicates that 
the
+        *            cause is nonexistent or unknown)
+        */
+       public MartServiceException(Throwable cause) {
+               super(cause);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-bioinformatics/blob/9e08cac0/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceUtils.java
----------------------------------------------------------------------
diff --git 
a/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceUtils.java
 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceUtils.java
new file mode 100644
index 0000000..cdcb400
--- /dev/null
+++ 
b/taverna-biomart-martservice/src/main/java/org/biomart/martservice/MartServiceUtils.java
@@ -0,0 +1,725 @@
+/*
+ * Copyright (C) 2003 The University of Manchester 
+ *
+ * Modifications to the initial code base are copyright of their
+ * respective authors, or their employers as appropriate.  Authorship
+ * of the modifications may be determined from the ChangeLog placed at
+ * the end of this file.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ *
+ ****************************************************************
+ * Source code information
+ * -----------------------
+ * Filename           $RCSfile: MartServiceUtils.java,v $
+ * Revision           $Revision: 1.12 $
+ * Release status     $State: Exp $
+ * Last modified on   $Date: 2008/07/31 15:06:49 $
+ *               by   $Author: davidwithers $
+ * Created on 17-Mar-2006
+ *****************************************************************/
+package org.biomart.martservice;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.biomart.martservice.query.Attribute;
+import org.biomart.martservice.query.Dataset;
+import org.biomart.martservice.query.Query;
+import org.biomart.martservice.query.QueryXMLHandler;
+import org.ensembl.mart.lib.config.ConfigurationException;
+import org.ensembl.mart.lib.config.DatasetConfig;
+import org.ensembl.mart.lib.config.DatasetConfigXMLUtils;
+import org.jdom.DocType;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+import org.xml.sax.InputSource;
+
+/**
+ * Utility class for interacting with a BioMart web service.
+ * 
+ * @author David Withers
+ */
+public class MartServiceUtils {
+       private static Logger logger = Logger.getLogger(MartServiceUtils.class);
+
+       private static String lineSeparator = 
System.getProperty("line.separator");
+
+       public static final String QUERY_ATTRIBUTE = "query";
+
+       public static final String DATASET_ATTRIBUTE = "dataset";
+
+       public static final String MART_ATTRIBUTE = "mart";
+
+       public static final String SCHEMA_ATTRIBUTE = "virtualschema";
+
+       public static final String TYPE_ATTRIBUTE = "type";
+
+       public static final String MART_USER_ATTRIBUTE = "martuser";
+
+       public static final String INTERFACE_ATTRIBUTE = "interface";
+
+       public static final String REQUEST_ID_ATTRIBUTE = "requestid";
+
+       public static final String REGISTRY_VALUE = "registry";
+
+       public static final String VERSION_VALUE = "version";
+
+       public static final String DATASETS_VALUE = "datasets";
+
+       public static final String DATASET_VALUE = "dataset";
+
+       public static final String CONFIGURATION_VALUE = "configuration";
+
+       /**
+        * Sends a registry request to the Biomart webservice and constructs a
+        * MartRegistry from the XML returned by the webservice.
+        * 
+        * @param martServiceLocation
+        *            the URL of the Biomart webservice
+        * @return a MartRegistry
+        * @throws MartServiceException
+        *             if the Biomart webservice returns an error or is 
unavailable
+        */
+       public static MartRegistry getRegistry(String martServiceLocation,
+                       String requestId) throws MartServiceException {
+               List<NameValuePair> data = new ArrayList<NameValuePair>();
+               data.add(new NameValuePair(TYPE_ATTRIBUTE, REGISTRY_VALUE));
+               if (requestId != null) {
+                       data.add(new NameValuePair(REQUEST_ID_ATTRIBUTE, 
requestId));
+               }
+               HttpMethod method = new GetMethod(martServiceLocation);
+               method.setQueryString(data
+                               .toArray(new NameValuePair[data.size()]));
+               try {
+                       InputStream in = executeMethod(method, 
martServiceLocation);
+                       Document document = new SAXBuilder().build(in);
+                       Element root = document.getRootElement();
+                       return MartServiceXMLHandler.elementToRegistry(root,
+                                       Namespace.NO_NAMESPACE);
+               } catch (IOException e) {
+                       String errorMessage = "Error getting registry from "
+                                       + martServiceLocation;
+                       throw new MartServiceException(errorMessage, e);
+               } catch (JDOMException e) {
+                       String errorMessage = "Error getting registry from "
+                                       + martServiceLocation;
+                       throw new MartServiceException(errorMessage, e);
+               } finally {
+                       method.releaseConnection();
+               }
+
+       }
+
+       public static String getVersion(String martServiceLocation,
+                       String requestId, MartURLLocation mart) throws 
MartServiceException {
+               String errorMessage = "Error getting version from " + 
martServiceLocation;
+
+               List<NameValuePair> data = new ArrayList<NameValuePair>();
+               data.add(new NameValuePair(TYPE_ATTRIBUTE, VERSION_VALUE));
+               if (mart.getVirtualSchema() != null) {
+                       data.add(new NameValuePair(SCHEMA_ATTRIBUTE, mart
+                                       .getVirtualSchema()));
+               }
+               data.add(new NameValuePair(MART_ATTRIBUTE, mart.getName()));
+               if (requestId != null) {
+                       data.add(new NameValuePair(REQUEST_ID_ATTRIBUTE, 
requestId));
+               }
+               if (requestId != null) {
+                       data.add(new NameValuePair(REQUEST_ID_ATTRIBUTE, 
requestId));
+               }
+               HttpMethod method = new GetMethod(martServiceLocation);
+               method.setQueryString(data
+                               .toArray(new NameValuePair[data.size()]));
+               try {
+                       InputStream in = executeMethod(method, 
martServiceLocation);
+                       BufferedReader bufferedReader = new BufferedReader(
+                                       new InputStreamReader(in));
+                       String version = bufferedReader.readLine();
+                       if (version == null) {
+                               throw new MartServiceException(errorMessage + 
": No version returned");
+                       }
+                       version = version.trim();
+                       // fix for biomart's 'let's add a blank line' thing
+                       if ("".equals(version)) {
+                               version = bufferedReader.readLine();
+                               if (version == null) {
+                                       throw new 
MartServiceException(errorMessage + ": No version returned");
+                               }
+                               version = version.trim();
+                       }
+                       bufferedReader.close();
+                       return version;
+               } catch (IOException e) {
+                       throw new MartServiceException(errorMessage, e);
+               } finally {
+                       method.releaseConnection();
+               }
+       }
+
+       /**
+        * Sends a datasets request to the Biomart webservice and constructs an
+        * array of MartDataset from the tab separated rows of data returned by 
the
+        * webservice.
+        * 
+        * @param martServiceLocation
+        *            the URL of the Biomart webservice
+        * @param mart
+        *            the mart to get datasets from
+        * @return an array of MartDataset
+        * @throws MartServiceException
+        *             if the Biomart webservice returns an error or is 
unavailable
+        */
+       public static MartDataset[] getDatasets(String martServiceLocation,
+                       String requestId, MartURLLocation mart) throws 
MartServiceException {
+               List<NameValuePair> data = new ArrayList<NameValuePair>();
+               data.add(new NameValuePair(TYPE_ATTRIBUTE, DATASETS_VALUE));
+               if (mart.getVirtualSchema() != null) {
+                       data.add(new NameValuePair(SCHEMA_ATTRIBUTE, mart
+                                       .getVirtualSchema()));
+               }
+               data.add(new NameValuePair(MART_ATTRIBUTE, mart.getName()));
+               if (mart.getMartUser() != null) {
+                       data
+                                       .add(new 
NameValuePair(MART_USER_ATTRIBUTE, mart
+                                                       .getMartUser()));
+               }
+               if (requestId != null) {
+                       data.add(new NameValuePair(REQUEST_ID_ATTRIBUTE, 
requestId));
+               }
+               HttpMethod method = new GetMethod(martServiceLocation);
+               method.setQueryString(data
+                               .toArray(new NameValuePair[data.size()]));
+               try {
+                       InputStream in = executeMethod(method, 
martServiceLocation);
+
+                       MartDataset[] datasets = tabSeparatedReaderToDatasets(
+                                       new InputStreamReader(in), mart);
+                       in.close();
+                       return datasets;
+               } catch (IOException e) {
+                       String errorMessage = "Error getting datasets from "
+                                       + martServiceLocation;
+                       throw new MartServiceException(errorMessage, e);
+               } finally {
+                       method.releaseConnection();
+               }
+       }
+
+       /**
+        * Sends a configuration request to the Biomart webservice and 
constructs a
+        * DatasetConfig from the XML returned by the webservice.
+        * 
+        * @param martServiceLocation
+        *            the URL of the Biomart webservice
+        * @param dataset
+        *            the dataset to get the configuration for
+        * @return a DatasetConfig
+        * @throws MartServiceException
+        *             if the Biomart webservice returns an error or is 
unavailable
+        */
+       public static DatasetConfig getDatasetConfig(String martServiceLocation,
+                       String requestId, MartDataset dataset) throws 
MartServiceException {
+               List<NameValuePair> data = new ArrayList<NameValuePair>();
+               data.add(new NameValuePair(TYPE_ATTRIBUTE, 
CONFIGURATION_VALUE));
+               MartURLLocation mart = dataset.getMartURLLocation();
+               // if the dataset has a location specify the virtual schema to 
uniquely
+               // identify the dataset
+               if (mart != null && mart.getVirtualSchema() != null) {
+                       data.add(new NameValuePair(SCHEMA_ATTRIBUTE, mart
+                                       .getVirtualSchema()));
+               }
+               data.add(new NameValuePair(DATASET_VALUE, dataset.getName()));
+//             if (dataset.getInterface() != null) {
+//                     data.add(new NameValuePair(INTERFACE_ATTRIBUTE, dataset
+//                                     .getInterface()));
+//             }
+               if (mart != null && mart.getMartUser() != null) {
+                       data
+                                       .add(new 
NameValuePair(MART_USER_ATTRIBUTE, mart
+                                                       .getMartUser()));
+               }
+               if (requestId != null) {
+                       data.add(new NameValuePair(REQUEST_ID_ATTRIBUTE, 
requestId));
+               }
+               HttpMethod method = new GetMethod(martServiceLocation);
+               method.setQueryString(data
+                               .toArray(new NameValuePair[data.size()]));
+
+               try {
+                       InputStream in = executeMethod(method, 
martServiceLocation);
+
+                       DatasetConfigXMLUtils datasetConfigXMLUtils = new 
DatasetConfigXMLUtils(
+                                       true);
+                       SAXBuilder builder = new SAXBuilder();
+                       Document doc = builder.build(new InputSource(in));
+                       // Document doc = 
datasetConfigXMLUtils.getDocumentForXMLStream(in);
+
+                       DatasetConfig datasetConfig = datasetConfigXMLUtils
+                                       .getDatasetConfigForDocument(doc);
+                       
datasetConfigXMLUtils.loadDatasetConfigWithDocument(datasetConfig,
+                                       doc);
+                       return datasetConfig;
+               } catch (ConfigurationException e) {
+                       String errorMessage = "Error parsing configuration from 
"
+                                       + martServiceLocation;
+                       logger.debug(errorMessage, e);
+                       throw new MartServiceException(errorMessage, e);
+               } catch (JDOMException e) {
+                       String errorMessage = "Error parsing configuration from 
"
+                                       + martServiceLocation;
+                       logger.debug(errorMessage, e);
+                       throw new MartServiceException(errorMessage, e);
+               } catch (IOException e) {
+                       String errorMessage = "Error getting configuration from 
"
+                                       + martServiceLocation;
+                       logger.debug(errorMessage, e);
+                       throw new MartServiceException(errorMessage, e);
+               } finally {
+                       method.releaseConnection();
+               }
+       }
+
+       /**
+        * Sends a query to the Biomart webservice and constructs an array of 
List
+        * of String results from the tab separated rows of data returned by the
+        * webservice.
+        * 
+        * @param martServiceLocation
+        *            the URL of the Biomart webservice
+        * @param query
+        *            the query to send to the webservice
+        * @return an array of List of String
+        * @throws MartServiceException
+        *             if the Biomart webservice returns an error or is 
unavailable
+        */
+       public static Object[] getResults(String martServiceLocation,
+                       String requestId, Query query) throws 
MartServiceException {
+               Object[] results = new Object[0];
+               // int attributes = query.getAttributes().size();
+               int attributes = getAttributeCount(query.getAttributes());
+               boolean count = query.getCount() == 1;
+               // if there are no attributes and we're not doing a count 
there's no
+               // point in doing the query
+               if (attributes > 0 || count) {
+                       // The 'new' 0.5 server now resolves the attribute 
lists so there's
+                       // no need to do the split here any more
+                       // String queryXml = 
queryToXML(splitAttributeLists(query));
+                       String queryXml = queryToXML(query);
+                       logger.info(queryXml);
+                       NameValuePair[] data = { new 
NameValuePair(QUERY_ATTRIBUTE,
+                                       queryXml) };
+                       PostMethod method = new PostMethod(martServiceLocation);
+                       method.setRequestBody(data);
+
+                       try {
+                               InputStream in = executeMethod(method, 
martServiceLocation);
+                               if (query.getFormatter() == null) {
+                                       results = tabSeparatedReaderToResults(
+                                                       new 
InputStreamReader(in), count ? 1 : attributes);
+                                       if (!count) {
+                                               results = 
reassembleAttributeLists(results, query);
+                                       }
+                               } else {
+                                       results = readResult(in, 
query.getFormatter());
+                               }
+                               in.close();
+                       } catch (IOException e) {
+                               String errorMessage = "Error reading data from "
+                                               + martServiceLocation;
+                               throw new MartServiceException(errorMessage, e);
+                       } finally {
+                               method.releaseConnection();
+                       }
+
+               }
+
+               return results;
+       }
+
+       public static void putResults(String martServiceLocation, String 
requestId,
+                       Query query, ResultReceiver resultReceiver) throws 
MartServiceException, ResultReceiverException {
+               int attributeCount = getAttributeCount(query.getAttributes());
+               boolean count = query.getCount() == 1;
+               // if there are no attributes and we're not doing a count 
there's no
+               // point in doing the query
+               if (attributeCount > 0 || count) {
+                       String queryXml = queryToXML(query);
+                       logger.info(queryXml);
+                       NameValuePair[] data = { new 
NameValuePair(QUERY_ATTRIBUTE,
+                                       queryXml) };
+                       PostMethod method = new PostMethod(martServiceLocation);
+                       method.setRequestBody(data);
+
+                       try {
+                               InputStream in = executeMethod(method, 
martServiceLocation);
+                               if (query.getFormatter() == null) {
+                                       if (count) {
+                                               
resultReceiver.receiveResult(tabSeparatedReaderToResults(new 
InputStreamReader(in), 1), 0);
+                                       } else {
+                                               List<Attribute> attributes = 
query.getAttributes();
+                                               Object[] result = new 
Object[attributes.size()];
+                                               BufferedReader bufferedReader = 
new BufferedReader(new InputStreamReader(in));
+                                               String line = 
bufferedReader.readLine();
+                                               for (long i = 0; line != null; 
line = bufferedReader.readLine(), i++) {
+                                                       String[] tokens = 
line.split("\t", -1);
+                                                       if (attributeCount == 
tokens.length) {
+                                                               for (int ri = 
0, ti = 0; ri < result.length && ti < tokens.length; ri++) {
+                                                                       
Attribute attribute = attributes.get(ri);
+                                                                       if 
(attribute.getAttributes() == null) {
+                                                                               
result[ri] = tokens[ti];
+                                                                               
ti++;
+                                                                       } else {
+                                                                               
int nestedAttributeCount = attribute.getAttributesCount();
+                                                                               
List<Object> list = new ArrayList<Object>();
+                                                                               
for (int j = 0; j < nestedAttributeCount; j++) {
+                                                                               
        list.add(tokens[ti]);
+                                                                               
        ti++;
+                                                                               
}
+                                                                               
result[ri] = list;
+                                                                       }
+                                                               }
+                                                               
resultReceiver.receiveResult(result, i);
+                                                       } else {
+                                                               
resultReceiver.receiveError(line, i);
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       
resultReceiver.receiveResult(readResult(in, query.getFormatter()), 0);
+                               }
+                               in.close();
+                       } catch (IOException e) {
+                               String errorMessage = "Error reading data from "
+                                               + martServiceLocation;
+                               throw new MartServiceException(errorMessage, e);
+                       } finally {
+                               method.releaseConnection();
+                       }
+
+               }
+       }
+       
+//     private static String getLocation(MartURLLocation martUrlLocation) {
+//             StringBuffer location = new StringBuffer("http://";);
+//             location.append(martUrlLocation.getHost());
+//             location.append(":" + martUrlLocation.getPort());
+//             location.append(martUrlLocation.getPath());
+//             return location.toString();
+//     }
+       
+       private static int getAttributeCount(List<Attribute> attributeList) {
+               int result = 0;
+               for (Attribute attribute : attributeList) {
+                       if (attribute.getAttributes() == null) {
+                               result++;
+                       } else {
+                               result += attribute.getAttributesCount();
+                       }
+               }
+               return result;
+       }
+
+       private static Object[] reassembleAttributeLists(Object[] lists, Query 
query) {
+               int index = 0;
+               List<Object> result = new ArrayList<Object>();
+               for (Attribute attribute : query.getAttributes()) {
+                       if (attribute.getAttributes() == null) {
+                               result.add(lists[index]);
+                               index++;
+                       } else {
+                               int attributesCount = 
attribute.getAttributesCount();
+                               List<Object> list = new ArrayList<Object>();
+                               for (int i = 0; i < attributesCount; i++) {
+                                       list.add(lists[index]);
+                                       index++;
+                               }
+                               result.add(list);
+                       }
+               }
+               return result.toArray();
+       }
+
+       public static Query splitAttributeLists(Query query) {
+               Query result = new Query(query);
+               for (Dataset dataset : result.getDatasets()) {
+                       List<Attribute> attributeList = dataset.getAttributes();
+                       dataset.removeAllAttributes();
+                       for (Attribute attribute : attributeList) {
+                               if (attribute.getAttributes() == null) {
+                                       dataset.addAttribute(attribute);
+                               } else {
+                                       String[] attributes = 
attribute.getAttributes().split(",");
+                                       for (int i = 0; i < attributes.length; 
i++) {
+                                               dataset.addAttribute(new 
Attribute(attributes[i]));
+                                       }
+                               }
+                       }
+               }
+               return result;
+       }
+
+       public static String getMimeTypeForFormatter(String formatter) {
+               String mimeType = "'text/plain'";
+               if ("ADF".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("AXT".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("AXTPLUS".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("CSV".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("FASTA".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("FASTACDNA".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("GFF".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("HTML".equals(formatter)) {
+                       mimeType = "'text/html'";
+               } else if ("MAF".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("MFA".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("MFASTA".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("TSV".equals(formatter)) {
+                       mimeType = "'text/tab-separeted-values'";
+               } else if ("TXT".equals(formatter)) {
+                       mimeType = "'text/plain'";
+               } else if ("XLS".equals(formatter)) {
+                       mimeType = "'application/excel'";
+               }
+               
+               return mimeType;
+       }
+       
+       private static List<String>[] tabSeparatedReaderToResults(Reader reader,
+                       int resultsCount) throws IOException {
+               List<String>[] results = new List[resultsCount];
+               for (int i = 0; i < results.length; i++) {
+                       results[i] = new ArrayList<String>();
+               }
+               BufferedReader bufferedReader = new BufferedReader(reader);
+               String line = bufferedReader.readLine();
+               while (line != null) {
+                       String[] tokens = line.split("\t", -1);
+                       for (int i = 0; i < results.length && i < 
tokens.length; i++) {
+                               results[i].add(tokens[i]);
+                       }
+                       line = bufferedReader.readLine();
+               }
+               return results;
+       }
+
+       private static Object[] readResult(InputStream inputStream, String 
formatter) throws IOException {
+               Object[] result = new Object[1];
+               
+               if 
(getMimeTypeForFormatter(formatter).contains("application/")) {
+                       result[0] = IOUtils.toByteArray(inputStream);
+               } else {
+                       result[0] = IOUtils.toString(inputStream);
+               }
+               return result;
+       }
+       
+       private static MartDataset[] tabSeparatedReaderToDatasets(Reader reader,
+                       MartURLLocation martURLLocation) throws IOException {
+               List<MartDataset> datasetList = new ArrayList<MartDataset>();
+               BufferedReader bufferedReader = new BufferedReader(reader);
+               String line = bufferedReader.readLine();
+               while (line != null) {
+                       String[] tokens = line.split("\t");
+
+                       if (tokens.length >= 7) {
+                               MartDataset dataset = new MartDataset();
+
+                               dataset.setType(tokens[0]);
+                               dataset.setName(tokens[1]);
+                               dataset.setDisplayName(tokens[2]);
+                               if (tokens[3].equals("1")) {
+                                       dataset.setVisible(true);
+                               } else {
+                                       dataset.setVisible(false);
+                               }
+                               // value at position 4 is not documented so 
it's skipped
+                               try {
+                                       
dataset.setInitialBatchSize(Long.parseLong(tokens[5]));
+                               } catch (NumberFormatException e) {
+                                       dataset.setInitialBatchSize(0);
+                               }
+                               try {
+                                       
dataset.setMaximumBatchSize(Long.parseLong(tokens[6]));
+                               } catch (NumberFormatException e) {
+                                       dataset.setMaximumBatchSize(0);
+                               }
+
+                               if (tokens.length > 7) {
+                                       dataset.setInterface(tokens[7]);
+                                       dataset.setModified(tokens[8]);
+                               }
+
+                               dataset.setMartURLLocation(martURLLocation);
+
+                               datasetList.add(dataset);
+                       }
+                       line = bufferedReader.readLine();
+               }
+               return datasetList.toArray(new MartDataset[datasetList.size()]);
+       }
+
+       /**
+        * Creates an XML string from a query
+        * 
+        * @param query
+        * @return an XML string
+        */
+       public static String queryToXML(Query query) {
+               Document document = new 
Document(QueryXMLHandler.queryToElement(query,
+                               Namespace.NO_NAMESPACE), new DocType("Query"));
+               return new XMLOutputter().outputString(document);
+       }
+
+       /**
+        * @param martServiceLocation
+        * @param data
+        * @return
+        * @throws MartServiceException
+        */
+       private static InputStream executeMethod(HttpMethod method,
+                       String martServiceLocation) throws MartServiceException 
{
+               HttpClient client = new HttpClient();
+               if (isProxyHost(martServiceLocation)) {
+                       setProxy(client);
+               }
+
+               method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
+                               new DefaultHttpMethodRetryHandler(3, false));
+//             method.getParams().setSoTimeout(60000);
+               try {
+                       int statusCode = client.executeMethod(method);
+                       if (statusCode != HttpStatus.SC_OK) {
+                               throw constructException(method, 
martServiceLocation, null);
+                       }
+                       return method.getResponseBodyAsStream();
+               } catch (IOException e) {
+                       throw constructException(method, martServiceLocation, 
e);
+               }
+       }
+
+       /**
+        * 
+        * @param client
+        */
+       public static void setProxy(HttpClient client) {
+               String host = System.getProperty("http.proxyHost");
+               String port = System.getProperty("http.proxyPort");
+               String user = System.getProperty("http.proxyUser");
+               String password = System.getProperty("http.proxyPassword");
+
+               if (host != null && port != null) {
+                       try {
+                               int portInteger = Integer.parseInt(port);
+                               client.getHostConfiguration().setProxy(host, 
portInteger);
+                               if (user != null && password != null) {
+                                       client.getState().setProxyCredentials(
+                                                       new AuthScope(host, 
portInteger),
+                                                       new 
UsernamePasswordCredentials(user, password));
+                               }
+                       } catch (NumberFormatException e) {
+                               logger.error("Proxy port not an integer", e);
+                       }
+               }
+       }
+
+       public static boolean isProxyHost(String location) {
+               String httpNonProxyHosts = 
System.getProperty("http.nonProxyHosts");
+               if (httpNonProxyHosts != null) {
+                       try {
+                               String host = new URL(location).getHost();
+                               String[] nonProxyHosts = 
httpNonProxyHosts.split("\\|");
+                               for (int i = 0; i < nonProxyHosts.length; i++) {
+                                       if (nonProxyHosts[i].startsWith("*")) {
+                                               if 
(host.endsWith(nonProxyHosts[i].substring(1))) {
+                                                       return false;
+                                               }
+                                       } else if 
(nonProxyHosts[i].endsWith("*")) {
+                                               if 
(host.startsWith(nonProxyHosts[i].substring(0,
+                                                               
nonProxyHosts[i].length() - 1))) {
+                                                       return false;
+                                               }
+                                       } else {
+                                               if 
(host.equals(nonProxyHosts[i])) {
+                                                       return false;
+                                               }
+                                       }
+                               }
+                       } catch (MalformedURLException e) {
+                               logger.warn("'" + location + "' is not a valid 
URL. "
+                                               + "Cannot compare host with 
http.nonProxyHosts", e);
+                       }
+               }
+               return true;
+       }
+
+       private static MartServiceException constructException(HttpMethod 
method,
+                       String martServiceLocation, Exception cause) {
+               StringBuffer errorMessage = new StringBuffer();
+               errorMessage.append("Error posting to " + martServiceLocation
+                               + lineSeparator);
+               if (cause == null) {
+                       errorMessage.append(" " + method.getStatusLine()
+                                       + lineSeparator);
+               }
+               if (method instanceof PostMethod) {
+                       PostMethod postMethod = (PostMethod) method;
+                       NameValuePair[] data = postMethod.getParameters();
+                       for (int i = 0; i < data.length; i++) {
+                               errorMessage.append(" " + data[i].getName() + " 
= "
+                                               + data[i].getValue()
+                                               + lineSeparator);
+                       }
+
+               } else {
+                       errorMessage.append(method.getQueryString());
+               }
+               return new MartServiceException(errorMessage.toString(), cause);
+       }
+
+}

Reply via email to