Das client files
authoramwaterhouse <Andrew Waterhouse>
Thu, 15 Jun 2006 13:03:02 +0000 (13:03 +0000)
committeramwaterhouse <Andrew Waterhouse>
Thu, 15 Jun 2006 13:03:02 +0000 (13:03 +0000)
33 files changed:
src/org/biojava/dasobert/das/AlignmentParameters.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_DNA_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_Entry_Points_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_FeatureRetrieve.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_Feature_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_Sequence_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_StylesheetRetrieve.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_Stylesheet_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/DAS_Types_Handler.java [new file with mode: 0755]
src/org/biojava/dasobert/das/FeatureThread.java [new file with mode: 0755]
src/org/biojava/dasobert/das/SequenceThread.java [new file with mode: 0755]
src/org/biojava/dasobert/das/SpiceDasSource.java [new file with mode: 0755]
src/org/biojava/dasobert/das/Xpm.java [new file with mode: 0755]
src/org/biojava/dasobert/das2/Das2Capability.java [new file with mode: 0755]
src/org/biojava/dasobert/das2/Das2CapabilityImpl.java [new file with mode: 0755]
src/org/biojava/dasobert/das2/Das2Source.java [new file with mode: 0755]
src/org/biojava/dasobert/das2/Das2SourceImpl.java [new file with mode: 0755]
src/org/biojava/dasobert/das2/DasSourceConverter.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/Das1Source.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/Das1Validator.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/Das2Validator.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/DasCoordSysComparator.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/DasCoordinateSystem.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/DasSource.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/DasSourceComparator.java [new file with mode: 0755]
src/org/biojava/dasobert/dasregistry/DasSourceValidator.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/AlignmentListener.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/FeatureEvent.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/FeatureListener.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/ObjectListener.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/SequenceEvent.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/SequenceListener.java [new file with mode: 0755]
src/org/biojava/dasobert/eventmodel/StructureListener.java [new file with mode: 0755]

diff --git a/src/org/biojava/dasobert/das/AlignmentParameters.java b/src/org/biojava/dasobert/das/AlignmentParameters.java
new file mode 100755 (executable)
index 0000000..faf6924
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Dec 10, 2005
+ *
+ */
+package org.biojava.dasobert.das;
+
+import org.biojava.dasobert.dasregistry.Das1Source;
+import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
+
+/** a class that stores the arguments that can be sent to the AlignmentThread class
+ * 
+ * @author Andreas Prlic
+ *
+ */
+public class AlignmentParameters {
+
+    String query;
+    String subject;
+    String queryPDBChainId;
+    String subjectPDBChainId;
+    
+    
+    DasCoordinateSystem queryCoordinateSystem;
+    DasCoordinateSystem subjectCoordinateSystem;
+    Das1Source[] dasSources;
+    
+    
+    public static String DEFAULT_PDBCOORDSYS     = "PDBresnum,Protein Structure";
+    public static String DEFAULT_UNIPROTCOORDSYS = "UniProt,Protein Sequence";
+    public static String DEFAULT_ENSPCOORDSYS    = "Ensembl,Protein Sequence";
+    
+    
+    public AlignmentParameters() {
+        super();
+        dasSources = new SpiceDasSource[0];
+
+    }
+
+    public DasCoordinateSystem getDefaultPDBCoordSys(){
+        return DasCoordinateSystem.fromString(DEFAULT_PDBCOORDSYS);
+    }
+    public DasCoordinateSystem getDefaultUniProtCoordSys(){
+        return DasCoordinateSystem.fromString(DEFAULT_UNIPROTCOORDSYS);
+    }
+    public DasCoordinateSystem getDefaultEnspCoordSys(){
+        return DasCoordinateSystem.fromString(DEFAULT_ENSPCOORDSYS);
+    }
+    
+
+    public Das1Source[] getDasSources() {
+        return dasSources;
+    }
+
+
+
+    public void setDasSources(SpiceDasSource[] dasSources) {
+        this.dasSources = dasSources;
+    }
+
+
+
+    public String getQuery() {
+        return query;
+    }
+
+
+
+    public void setQuery(String query) {
+        this.query = query;
+    }
+
+
+
+    public DasCoordinateSystem getQueryCoordinateSystem() {
+        return queryCoordinateSystem;
+    }
+
+
+
+    public void setQueryCoordinateSystem(DasCoordinateSystem queryCoordinateSystem) {
+        this.queryCoordinateSystem = queryCoordinateSystem;
+    }
+
+
+
+    public String getQueryPDBChainId() {
+        return queryPDBChainId;
+    }
+
+
+
+    public void setQueryPDBChainId(String queryPDBChainId) {
+        this.queryPDBChainId = queryPDBChainId;
+    }
+
+
+
+    public String getSubject() {
+        return subject;
+    }
+
+
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+
+
+    public DasCoordinateSystem getSubjectCoordinateSystem() {
+        return subjectCoordinateSystem;
+    }
+
+
+
+    public void setSubjectCoordinateSystem(
+            DasCoordinateSystem subjectCoordinateSystem) {
+        this.subjectCoordinateSystem = subjectCoordinateSystem;
+    }
+
+
+
+    public String getSubjectPDBChainId() {
+        return subjectPDBChainId;
+    }
+
+
+
+    public void setSubjectPDBChainId(String subjectPDBChainId) {
+        this.subjectPDBChainId = subjectPDBChainId;
+    }
+    
+    
+    
+
+}
diff --git a/src/org/biojava/dasobert/das/DAS_DNA_Handler.java b/src/org/biojava/dasobert/das/DAS_DNA_Handler.java
new file mode 100755 (executable)
index 0000000..49b1ad1
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das;
+
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes;
+
+/**
+ * a class to parse the XML response of a DAS-DNA request.
+ * @author andreas
+ */
+public class DAS_DNA_Handler extends DefaultHandler {
+
+       String sequence ;
+       int length ;
+       boolean dna_flag; 
+       /**
+        * 
+        */
+       public DAS_DNA_Handler() {
+               super();
+               // TODO Auto-generated constructor stub
+               sequence = "" ;
+               length = 0;
+               dna_flag = false ;
+       }
+
+       public void startElement (String uri, String name, String qName, Attributes atts){
+
+           if ( qName.equals("DNA")){
+               //System.out.println("new element >" + name + "< >" + qName+"<");
+               // was : length
+               String lenstr   = atts.getValue("length");
+               length = Integer.parseInt(lenstr);
+               dna_flag = true ;
+           }
+               
+       }
+       
+       public void characters (char ch[], int start, int length){
+           //System.out.print("Characters:    \"");
+               if (dna_flag) 
+                for (int i = start; i < start + length; i++) {
+                       switch (ch[i]) {
+                       case '\\':
+                               //System.out.print("\\\\");
+                               break;
+                       case '"':
+                               //System.out.print("\\\"");
+                               break;
+                       case '\n':
+                               //System.out.print("\\n");
+                               break;
+                       case '\r':
+                               //System.out.print("\\r");
+                               break;
+                       case '\t':
+                               //System.out.print("\\t");
+                               break;
+                       case ' ':
+                               break;
+                       default:
+                               sequence = sequence + ch[i];
+                               //System.out.print(ch[i]);
+                break;
+                }
+                }
+                //System.out.print("\"\n");
+                
+       }
+       
+       public String get_sequence() {
+               if ( length != sequence.length()) {             
+                       System.err.println("Sequence does not match specified length!");
+               }
+               
+               return sequence;
+       }
+               
+       
+       
+}
diff --git a/src/org/biojava/dasobert/das/DAS_Entry_Points_Handler.java b/src/org/biojava/dasobert/das/DAS_Entry_Points_Handler.java
new file mode 100755 (executable)
index 0000000..9afa621
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das ;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes;
+
+
+/** a class to parse the reponse of a DAS - types request 
+ */
+public class DAS_Entry_Points_Handler extends DefaultHandler {
+    String version ;
+    
+    public DAS_Entry_Points_Handler() {
+       super();
+       
+       version = null;
+    }
+
+    public void startElement (String uri, String name, String qName, Attributes atts){
+       if ( qName.equals("DASEP")) {
+           
+       }  else if ( qName.equals("ENTRY_POINTS")) {
+        
+           String v = atts.getValue("version");
+           version = v;            
+       }       
+    }
+    
+    /** returns true if the server returns an entry points */
+    public String getVersion() {
+       return version;
+    }
+   
+}
+
diff --git a/src/org/biojava/dasobert/das/DAS_FeatureRetrieve.java b/src/org/biojava/dasobert/das/DAS_FeatureRetrieve.java
new file mode 100755 (executable)
index 0000000..e6319f1
--- /dev/null
@@ -0,0 +1,230 @@
+/**
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das;
+
+
+import java.net.URL                         ;
+import java.io.InputStream                  ;
+import org.xml.sax.InputSource              ;
+import org.xml.sax.XMLReader                ;
+import javax.xml.parsers.*                  ;
+import org.xml.sax.*                        ;
+import java.util.ArrayList                  ;
+import java.util.List;
+import java.util.logging.*                  ;
+import java.net.HttpURLConnection           ;
+import java.io.IOException;
+import java.net.ConnectException;
+import java.lang.reflect.Method;
+
+
+/**
+ * A class to perform a DAS features request
+ *
+ * @author Andreas Prlic
+ *
+ */
+public class DAS_FeatureRetrieve {
+
+    List features ;
+    Logger logger     ;
+    int comeBackLater;
+    URL url;
+    /**
+     *
+     */
+    public DAS_FeatureRetrieve(URL url) {
+        super();
+
+        logger = Logger.getLogger("org.biojava.spice");
+        features = new ArrayList() ;
+        comeBackLater = -1;
+        this.url=url;
+        reload();
+    }
+
+
+    /** contact the DAS-feature server again. Usually
+     * it is not necessary to call this again, because the constructor already does, but
+     * if comeBackLater > -1 this should be called again.
+     *
+     */
+    public void reload(){
+
+        try {
+
+            InputStream dasInStream = null;
+            try {
+                dasInStream    = open(url);
+            } catch (Exception e ){
+                comeBackLater = -1;
+                logger.log(Level.FINE,"could not open connection to " + url,e);
+                return ;
+            }
+
+
+            SAXParserFactory spfactory =
+                SAXParserFactory.newInstance();
+
+            spfactory.setValidating(false);
+
+            SAXParser saxParser = null ;
+
+            try{
+                saxParser =
+                    spfactory.newSAXParser();
+            } catch (ParserConfigurationException e) {
+                e.printStackTrace();
+            }
+
+
+
+            String vali = System.getProperty("XMLVALIDATION");
+
+            boolean validation = false ;
+            if ( vali != null )
+                if ( vali.equals("true") )
+                    validation = true ;
+
+
+            XMLReader xmlreader = saxParser.getXMLReader();
+
+            //XMLReader xmlreader = XMLReaderFactory.createXMLReader();
+            try {
+                xmlreader.setFeature("http://xml.org/sax/features/validation", validation);
+            } catch (SAXException e) {
+                logger.log(Level.FINE,"Cannot set validation " + validation);
+            }
+
+            try {
+                xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",validation);
+            } catch (SAXNotRecognizedException e){
+                e.printStackTrace();
+                logger.log(Level.FINE,"Cannot set load-external-dtd "+validation);
+
+            }
+
+            DAS_Feature_Handler cont_handle = new DAS_Feature_Handler() ;
+            cont_handle.setDASCommand(url.toString());
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+            insource.setByteStream(dasInStream);
+
+            try {
+                xmlreader.parse(insource);
+                features = cont_handle.get_features();
+                comeBackLater = cont_handle.getComBackLater();
+            }
+            catch ( Exception e){
+              System.out.println("ERROR PARSING RESULT FROM "+url+ "\n"+e+"\n");
+               // e.printStackTrace();
+                logger.log(Level.FINE,"error while parsing response from "+ url);
+                comeBackLater = -1;
+                features = new ArrayList();
+            }
+        }
+        catch (Exception ex) {
+            ex.printStackTrace();
+            comeBackLater = -1;
+        }
+    }
+
+    /** open HttpURLConnection. Recommended way to open
+     * HttpURLConnections, since this take care of setting timeouts
+     * properly for java 1.4 and 1.5*/
+    public static HttpURLConnection openHttpURLConnection(URL url)
+    throws IOException, ConnectException {
+    HttpURLConnection huc = null;
+    huc = (HttpURLConnection) url.openConnection();
+
+    String os_name    = java.lang.System.getProperty("os.name");
+    String os_version = java.lang.System.getProperty("os.version");
+    String os_arch    = java.lang.System.getProperty("os.arch");
+    String VERSION = "1.0";
+
+    String userAgent = "Jalview " + VERSION + "("+os_name+"; "+os_arch + " ; "+ os_version+")";
+    //e.g. "Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.7.2) Gecko/20040803"
+     huc.addRequestProperty("User-Agent", userAgent);
+    //logger.finest("opening "+url);
+
+
+    // use reflection to determine if get and set timeout methods for urlconnection are available
+        // seems java 1.5 does not watch the System properties any longer...
+        // and java 1.4 did not provide these...
+    // for 1.4 see setSystemProperties
+    int timeout = 15000;
+    try {
+        // try to use reflection to set timeout property
+        Class urlconnectionClass = Class.forName("java.net.HttpURLConnection");
+
+            Method setconnecttimeout = urlconnectionClass.getMethod (
+                                     "setConnectTimeout", new Class [] {int.class}
+                                     );
+        setconnecttimeout.invoke(huc,new Object[] {new Integer(timeout)});
+
+        Method setreadtimeout = urlconnectionClass.getMethod (
+                                  "setReadTimeout", new Class[] {int.class}
+                                  );
+        setreadtimeout.invoke(huc,new Object[] {new Integer(timeout)});
+        //System.out.println("successfully set java 1.5 timeout");
+    } catch (Exception e) {
+        //e.printStackTrace();
+        // most likely it was a NoSuchMEthodException and we are running java 1.4.
+    }
+    return huc;
+    }
+
+    private InputStream open(URL url)
+    throws java.io.IOException, java.net.ConnectException
+    {
+        InputStream inStream = null;
+
+
+        HttpURLConnection huc = openHttpURLConnection(url);
+
+        inStream = huc.getInputStream();
+
+        return inStream;
+
+    }
+
+    /** returns a List of Features */
+    public List get_features() {
+
+        return features;
+    }
+
+    /** returns the comeBackLater value - if a server returned suchh -
+     *
+     * @return comeBackLater in seconds, or -1 if not provided by server
+     */
+    public int getComeBackLater(){
+
+        return comeBackLater;
+
+    }
+
+
+}
diff --git a/src/org/biojava/dasobert/das/DAS_Feature_Handler.java b/src/org/biojava/dasobert/das/DAS_Feature_Handler.java
new file mode 100755 (executable)
index 0000000..88eb57d
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes;
+
+import java.util.ArrayList ;
+import java.util.HashMap ;
+import java.util.List;
+
+/**
+ * a class to parse the response of a DAS - Feature request
+ * @author Andreas Prlic
+ *
+ */
+public class DAS_Feature_Handler  extends DefaultHandler{
+    
+    /**
+     * 
+     */
+    List features ;
+    boolean first_flag ;
+    HashMap feature ;
+    String featurefield ;
+    String characterdata ;
+    String dasCommand ;
+    
+    int comeBackLater ;
+    
+    public DAS_Feature_Handler() {
+        super();
+        
+        features= new ArrayList() ;
+        first_flag = true ;
+        featurefield = "" ;
+        characterdata = "";
+        dasCommand = "" ;
+        comeBackLater = -1; 
+    }
+    
+    public void setDASCommand(String cmd) { dasCommand = cmd ;}
+    public String getDASCommand() { return dasCommand; }
+    
+    public List get_features() {
+        return features ;
+    }
+    
+    public int getComBackLater(){
+        return comeBackLater;
+    }
+    
+    void start_feature(String uri, String name, String qName, Attributes atts) {
+        feature = new HashMap() ;
+        String id      = atts.getValue("id");
+        feature.put("id",id);
+        feature.put("dassource",dasCommand);
+        characterdata = "";
+    }
+    
+    void add_featuredata(String uri, String name, String qName) {
+        //System.out.println("featurefield "+featurefield+ " data "+characterdata);
+        // NOTE can have multiple lines ..
+        
+        String data = (String)feature.get(featurefield);
+        if (data != null){
+            characterdata = data + " " + characterdata;
+        }
+        
+        feature.put(featurefield,characterdata);
+        featurefield = "";
+        characterdata = "";
+    }
+    
+    private void addLink(String uri, String name, String qName, Attributes atts) {
+        String href = atts.getValue("href");
+        feature.put("LINK",href);
+        characterdata="";
+        featurefield = "LINK-TEXT";
+                
+    }
+    
+    public void startElement (String uri, String name, String qName, Attributes atts){
+        //System.out.println("new element "+qName);
+        
+        if (qName.equals("FEATURE")) 
+            start_feature(uri,  name,  qName,  atts);
+        else if ( qName.equals("LINK"))
+            addLink(uri,name,qName, atts);
+        else if ( qName.equals("METHOD") || 
+                qName.equals("TYPE") ||
+                qName.equals("START") ||
+                qName.equals("END") ||
+                qName.equals("NOTE") ||                
+                qName.equals("SCORE")
+        ){
+            characterdata ="";
+            featurefield = qName ;
+        }
+        
+    }
+    
+    public void startDocument() {
+        //System.out.println("start document");
+    }
+    
+    public void endDocument () {
+        //System.out.println("adding feature " + feature);
+        //features.add(feature);
+        
+    }
+    public void endElement(String uri, String name, String qName) {
+        //System.out.println("end "+name);
+        if ( qName.equals("METHOD") || 
+                qName.equals("TYPE") ||
+                qName.equals("START") ||
+                qName.equals("END") ||
+                qName.equals("NOTE") || 
+                qName.equals("LINK") || 
+                qName.equals("SCORE")
+        ) {
+            add_featuredata(uri,name,qName);
+        }
+        else if ( qName.equals("FEATURE")) {
+            //System.out.println("adding ffeature " + feature);
+            features.add(feature);
+        }
+    }
+    
+    public void characters (char ch[], int start, int length){
+        //System.out.println("characters");
+        for (int i = start; i < start + length; i++) {
+            
+            characterdata += ch[i];
+        }
+        
+    }
+    
+}
diff --git a/src/org/biojava/dasobert/das/DAS_Sequence_Handler.java b/src/org/biojava/dasobert/das/DAS_Sequence_Handler.java
new file mode 100755 (executable)
index 0000000..0d39e15
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das;
+
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes            ;
+import java.util.logging.*                ;
+
+/**
+ * a class that parses the XML response of a DAS - sequence command.
+ * @author Andreas Prlic
+ *
+ */
+public class DAS_Sequence_Handler extends DefaultHandler {
+
+       String sequence ;
+       int length ;
+       boolean dna_flag; 
+       /**
+        * 
+        */
+       public DAS_Sequence_Handler() {
+               super();
+               // TODO Auto-generated constructor stub
+               sequence = "" ;
+               length = 0;
+               dna_flag = false ;
+       }
+
+       public void startElement (String uri, String name, String qName, Attributes atts){
+
+           if ( qName.equals("SEQUENCE")){
+               //System.out.println("new element >" + name + "< >" + qName+"<");
+               // was : length
+               String lenstr   = atts.getValue("stop");
+               length = Integer.parseInt(lenstr);
+               dna_flag = true ;
+           }
+               
+       }
+       
+       public void characters (char ch[], int start, int length){
+           //System.out.print("Characters:    \"");
+               if (dna_flag) 
+                for (int i = start; i < start + length; i++) {
+                       switch (ch[i]) {
+                       case '\\':
+                               //System.out.print("\\\\");
+                               break;
+                       case '"':
+                               //System.out.print("\\\"");
+                               break;
+                       case '\n':
+                               //System.out.print("\\n");
+                               break;
+                       case '\r':
+                               //System.out.print("\\r");
+                               break;
+                       case '\t':
+                               //System.out.print("\\t");
+                               break;
+                       case ' ':
+                               break;
+                       default:
+                               sequence = sequence + ch[i];
+                               //System.out.print(ch[i]);
+                break;
+                }
+                }
+                //System.out.print("\"\n");
+                
+       }
+       
+       public String get_sequence() {
+               if ( length != sequence.length()) {     
+                   Logger logger  = Logger.getLogger("org.biojava.spice");
+                   logger.warning("Sequence does not match specified length!");
+                       
+               }
+               
+               return sequence;
+       }
+               
+       
+       
+}
diff --git a/src/org/biojava/dasobert/das/DAS_StylesheetRetrieve.java b/src/org/biojava/dasobert/das/DAS_StylesheetRetrieve.java
new file mode 100755 (executable)
index 0000000..8411aca
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on Aug 3, 2005
+ *
+ */
+package org.biojava.dasobert.das;
+
+import java.io.InputStream;
+import java.net.*;
+import java.util.*;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/** this stores the stylesheet config for a DAS source.
+ *
+ * @author Andreas Prlic
+ *
+ */
+public class DAS_StylesheetRetrieve {
+    static Logger logger = Logger.getLogger("org.biojava.spice");
+    /**
+     *
+     */
+    Map[] t3DMap;
+    public DAS_StylesheetRetrieve() {
+        super();
+
+    }
+
+    /** retrieve a StyleSheet from a URL
+     * The style sheet is represented as a Map[],
+     *  where each Map contains the description of how to draw a features of a particular type.
+     *
+     *  */
+    public Map[] retrieve(URL dasStylesheetRequest){
+
+        logger.finest("requesting stylesheet from " + dasStylesheetRequest);
+
+        InputStream inStream = null;
+
+               try {
+                   HttpURLConnection huc = DAS_FeatureRetrieve.openHttpURLConnection(dasStylesheetRequest);
+
+                   logger.finest("got connection: "+huc.getResponseMessage());
+                   //String contentEncoding = huc.getContentEncoding();
+                   inStream = huc.getInputStream();
+
+
+                   SAXParserFactory spfactory =
+                           SAXParserFactory.newInstance();
+
+                       spfactory.setValidating(false);
+
+                   SAXParser saxParser = null ;
+
+                       try{
+                           saxParser =
+                               spfactory.newSAXParser();
+                       } catch (ParserConfigurationException e) {
+                           e.printStackTrace();
+                       }
+
+                       DAS_Stylesheet_Handler cont_handle = new DAS_Stylesheet_Handler() ;
+                       XMLReader xmlreader = saxParser.getXMLReader();
+
+                       xmlreader.setContentHandler(cont_handle);
+                       xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+                       InputSource insource = new InputSource() ;
+                       insource.setByteStream(inStream);
+
+
+                   xmlreader.parse(insource);
+                       Map[] typeMap = cont_handle.getTypeStyles();
+
+                       t3DMap = cont_handle.get3DStyles();
+                       return typeMap;
+
+               } catch (Exception e) {
+                   logger.finest(e.getMessage());
+                   return null;
+               }
+    }
+
+
+    public Map[] get3DStyle(){
+        return t3DMap;
+    }
+}
diff --git a/src/org/biojava/dasobert/das/DAS_Stylesheet_Handler.java b/src/org/biojava/dasobert/das/DAS_Stylesheet_Handler.java
new file mode 100755 (executable)
index 0000000..561177b
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Aug 3, 2005
+ *
+ */
+package org.biojava.dasobert.das;
+
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes            ;
+import java.util.*;
+import java.util.logging.Logger;
+import java.awt.Color;
+
+/** a class to parse the XML response of a DAS - stylesheet request.
+ * @author Andreas Prlic
+ *
+ */
+public class DAS_Stylesheet_Handler extends DefaultHandler {
+    
+    List typeGlyphMaps;
+    Map  currentType;
+    String chars ;
+    boolean threeDstyle;
+    List threeDGlyphMaps;
+    static Logger logger      = Logger.getLogger("org.biojava.spice");
+    
+    /**
+     * 
+     */
+    public DAS_Stylesheet_Handler() {
+        super();
+        typeGlyphMaps = new ArrayList();
+        currentType = new HashMap();
+        threeDGlyphMaps = new ArrayList();
+        threeDstyle = false;
+    }
+    
+    
+    public Map[] getTypeStyles(){
+        return (Map[]) typeGlyphMaps.toArray(new Map[typeGlyphMaps.size()]);
+    }
+    
+    public Map[] get3DStyles(){
+        return (Map[]) threeDGlyphMaps.toArray(new Map[threeDGlyphMaps.size()]);
+    }
+    
+    public void startElement (String uri, String name, String qName, Attributes atts){
+        chars = "";
+        
+        if ( qName.equals("CATEGORY")){
+            String id = atts.getValue("id");
+            if ( id.equals("3D")){
+                // here follow the 3D styles...
+                threeDstyle = true;
+            } else {
+                threeDstyle = false;
+                
+            }
+        }
+        
+        if ( qName.equals("TYPE")){
+            // this glyph matches to features of type >id<.
+            String id = atts.getValue("id");
+            currentType = new HashMap(); 
+            currentType.put("type",id);
+        } 
+        
+        else if ( qName.equals("ARROW")){
+            currentType.put("style","arrow");
+        } else if ( qName.equals("ANCHORED_ARROW")){
+            currentType.put("style","anchored_arrow");
+        } else if ( qName.equals("BOX")){
+            currentType.put("style","box");
+        } else if ( qName.equals("CROSS")){
+            currentType.put("style","cross");
+        } else if ( qName.equals("EX")){
+            currentType.put("style","EX");
+        } else if ( qName.equals("HELIX")){
+            currentType.put("style","helix");
+        } else if ( qName.equals("LINE")){
+            currentType.put("style","LINE");
+        }  else if ( qName.equals("SPAN")){
+            currentType.put("style","span");
+        } else if ( qName.equals("TRIANGLE")){
+            currentType.put("style","triangle");
+        }
+        
+    }
+    
+    /**  convert the color provided by the stylesheet to a java Color 
+     * 
+     * @param chars
+     * @return
+     */
+    private Color getColorFromString(String chars){
+        
+        
+        if (chars.equals("rotate")) {
+            // use the default SPICE colors ...
+            return null;
+        }
+        
+        try {
+            Color col = Color.decode(chars);
+            return col;
+        } catch ( Exception e) {
+            logger.finest("could not decode color from stylesheet " + e.getMessage());
+        }
+        
+        
+        // map the string to a build in color...
+        // thanks to the Xpm.java script provided by Phil Brown (under LGPL)
+        // AP downloaded it from http://www.bolthole.com/java/Xpm.java
+        
+        // the DAS spec stylesheet only requires 16 VGA colors to be supported, but here we do more... :-)
+        
+        int[] rgb = Xpm.NameToRGB3(chars);
+        if ( rgb != null) {
+            Color col = new Color(rgb[0],rgb[1],rgb[2]);
+            return col;
+        }
+        return null ;
+    }
+    
+    public void endElement(String uri, String name, String qName) {
+        if ( qName.equals("HEIGHT")){
+            currentType.put("height",chars);
+        } else if ( qName.equals("COLOR")){
+            //System.out.println("got color " + chars);
+            Color col = getColorFromString(chars);
+            if ( col != null ){
+                currentType.put("color",col);
+            } else {
+                if ( chars.equals("cpk")){
+                    currentType.put("cpkcolor","true");
+                }
+            }
+            
+        } else if ( qName.equals("OUTLINECOLOR")){
+            currentType.put("outlinecolor",chars);
+        } else if ( qName.equals("BACKGROUND")){
+            currentType.put("background",chars);
+        } else if ( qName.equals("BUMP")){
+            if ( chars.equals("no"))
+                currentType.put("bump","no");
+            else 
+                currentType.put("bump","yes");
+        
+            // 3D stuff
+        }  else if ( qName.equals("WIREFRAME")){
+            currentType.put("display","wireframe");
+        } else if ( qName.equals("SPACEFILL")){
+            currentType.put("display","spacefill");
+        } else if ( qName.equals("BACKBONE")){
+            currentType.put("display","backbone");
+        } else if ( qName.equals("CARTOON")){
+            currentType.put("display","cartoon");
+        } else if ( qName.equals("RIBBONS")){
+            currentType.put("display","ribbons");
+        } else if ( qName.equals("WIDTH")){
+            currentType.put("width",chars);
+        }
+        
+        else if ( qName.equals("TYPE")){           
+            if ( threeDstyle){
+             threeDGlyphMaps.add(currentType);   
+            } else {
+                typeGlyphMaps.add(currentType);
+            }
+        }
+    }
+    
+    public void characters (char ch[], int start, int length){
+        
+     
+            for (int i = start; i < start + length; i++) {
+               chars += ch[i];
+            }
+        
+        
+    }
+    
+}
+
+
+
+
diff --git a/src/org/biojava/dasobert/das/DAS_Types_Handler.java b/src/org/biojava/dasobert/das/DAS_Types_Handler.java
new file mode 100755 (executable)
index 0000000..162cf39
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 19.03.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.das ;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.Attributes;
+
+import java.util.ArrayList ;
+import java.util.List;
+
+
+/** a class to parse the reponse of a DAS - types request 
+ */
+public class DAS_Types_Handler extends DefaultHandler {
+    List types;
+    boolean dastypesPresent;
+    boolean gffPresent;
+    boolean segmentPresent;
+    
+    public DAS_Types_Handler() {
+       super();
+       types = new ArrayList();
+       dastypesPresent = false;
+       gffPresent=false;
+       segmentPresent=false;
+    }
+
+    public void startElement (String uri, String name, String qName, Attributes atts){
+       if ( qName.equals("DASTYPES")) {
+           dastypesPresent = true;
+           
+       } else if ( qName.equals("GFF")) {
+           gffPresent = true;
+           
+       } else if ( qName.equals("SEGMENT")) {
+           segmentPresent = true;      
+        
+           String id = atts.getValue("id");
+           // id is optional here
+           if ( id != null ) {
+               types.add(id);
+           }
+       } else if ( qName.equals("TYPE")){
+           String type = atts.getValue("id");
+           // id is mandatory ...          
+           types.add(type);
+           
+       }
+       
+    }
+
+    public String[] getTypes(){
+       return (String[])types.toArray(new String[types.size()]);
+    }
+}
+
diff --git a/src/org/biojava/dasobert/das/FeatureThread.java b/src/org/biojava/dasobert/das/FeatureThread.java
new file mode 100755 (executable)
index 0000000..7435cdb
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 21.09.2004
+ * @author Andreas Prlic
+ *
+ */
+
+package org.biojava.dasobert.das ;
+
+import java.util.*;
+import java.net.*;
+import java.util.logging.* ;
+import org.biojava.dasobert.eventmodel.FeatureListener;
+import org.biojava.dasobert.eventmodel.FeatureEvent;
+import org.biojava.dasobert.dasregistry.Das1Source;
+
+/** a thread that connects to a DAS - Feature service and gets the features
+ *
+ * @author Andreas Prlic
+ */
+
+
+
+public class FeatureThread
+    implements Runnable
+{
+
+    /** number of times the client tries to reconnect to the server if a "come back later" is returned.
+     * the server should provide a reasonable estimation how long it will take him to create results.
+     * if this number of requests is still not successfull, give up.
+     */
+    public static int MAX_COME_BACK_ITERATIONS = 5;
+
+    public static int MAX_NR_FEATURES = 300;
+
+    static Logger logger = Logger.getLogger("org.biojava.spice");
+
+    Das1Source dasSource;
+    String ac ;
+    List featureListeners;
+    Thread thread;
+
+    public FeatureThread (String accessionCode, Das1Source dasSource) {
+       this.dasSource = dasSource;
+       this.ac = accessionCode;
+       featureListeners = new ArrayList();
+    }
+
+    public void addFeatureListener(FeatureListener li) {
+       featureListeners.add(li);
+    }
+
+    public void clearFeatureListeners() {
+       featureListeners.clear();
+    }
+
+    public synchronized void stop(){
+       thread = null;
+       notify();
+    }
+
+
+
+
+    public void run() {
+       Thread me = Thread.currentThread();
+       while ( thread == me) {
+           String url = dasSource.getUrl();
+           String queryString = url + "features?segment="+ ac ;
+           URL cmd = null ;
+           try {
+               cmd = new URL(queryString);
+           } catch (MalformedURLException e ) {
+               logger.warning("got MalformedURL from das source " +dasSource);
+               e.printStackTrace();
+           }
+
+           logger.info("requesting features from " + cmd);
+           DAS_FeatureRetrieve ftmp = new DAS_FeatureRetrieve(cmd);
+
+
+           int comeBackLater = ftmp.getComeBackLater();
+           int securityCounter = 0;
+           while ( (thread == me) && ( comeBackLater > 0 )) {
+               securityCounter++;
+               if ( securityCounter >= MAX_COME_BACK_ITERATIONS){
+                   comeBackLater = -1;
+                   break;
+
+               }
+               notifyComeBackLater(comeBackLater);
+               // server is still calculating - asks us to come back later
+               try {
+                   wait (comeBackLater);
+               } catch (InterruptedException e){
+                   comeBackLater = -1;
+                   break;
+               }
+
+               ftmp.reload();
+               comeBackLater = ftmp.getComeBackLater();
+           }
+
+           if ( ! (thread == me ) ) {
+               break;
+           }
+
+           List features = ftmp.get_features();
+
+           // a fallback mechanism to prevent DAS sources from bringing down spice
+           if ( features.size() > MAX_NR_FEATURES){
+               logger.warning("DAS source returned more than " + MAX_NR_FEATURES + "features. " +
+                              " throwing away excess features at " +cmd);
+               features = features.subList(0,MAX_NR_FEATURES);
+           }
+
+
+           // notify FeatureListeners
+           Map[] feats = (Map[])features.toArray(new Map[features.size()]);
+           notifyFeatureListeners(feats);
+
+           break;
+
+
+       }
+       thread = null;
+
+    }
+
+    public void start() {
+       thread = new Thread(this);
+       thread.start();
+    }
+
+    private void notifyFeatureListeners(Map[] feats){
+        logger.finest("FeatureThread found " + feats.length + " features");
+        FeatureEvent fevent = new FeatureEvent(feats,dasSource);
+        Iterator fiter = featureListeners.iterator();
+        while (fiter.hasNext()){
+            FeatureListener fi = (FeatureListener)fiter.next();
+            fi.newFeatures(fevent);
+        }
+    }
+
+ /** the Annotation server requested to be queried again in a while
+     *
+     * @param comeBackLater
+     */
+    private void notifyComeBackLater(int comeBackLater){
+        FeatureEvent event = new FeatureEvent(new HashMap[0],dasSource);
+        event.setComeBackLater(comeBackLater);
+        Iterator fiter = featureListeners.iterator();
+        while (fiter.hasNext()){
+            FeatureListener fi = (FeatureListener)fiter.next();
+            fi.comeBackLater(event);
+        }
+
+    }
+
+
+}
+
diff --git a/src/org/biojava/dasobert/das/SequenceThread.java b/src/org/biojava/dasobert/das/SequenceThread.java
new file mode 100755 (executable)
index 0000000..8f54a9f
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on Nov 20, 2005
+ *
+ */
+package org.biojava.dasobert.das;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.biojava.dasobert.dasregistry.Das1Source;
+import org.biojava.dasobert.eventmodel.SequenceEvent;
+import org.biojava.dasobert.eventmodel.SequenceListener;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.XMLReader;
+import java.util.*;
+
+/** a thread that gets the sequence from a DAS server
+ *
+ * @author Andreas Prlic
+ *
+ */
+public class SequenceThread
+extends Thread {
+
+    Das1Source[] sequenceServers;
+    String sp_accession;
+    List seqListeners;
+    static Logger logger = Logger.getLogger("org.biojava.spice");
+
+     public SequenceThread(String sp_accession,Das1Source ds ) {
+        super();
+        Das1Source[] dss =new Das1Source[1];
+       dss[0] = ds;
+        this.sp_accession = sp_accession;
+        this.sequenceServers =dss ;
+        clearSequenceListeners();
+    }
+    public SequenceThread(String sp_accession,Das1Source[] ds ) {
+        super();
+
+        this.sp_accession = sp_accession;
+        this.sequenceServers =ds ;
+        clearSequenceListeners();
+    }
+
+    public void clearSequenceListeners(){
+        seqListeners = new ArrayList();
+    }
+
+    public void addSequenceListener(SequenceListener lis){
+        seqListeners.add(lis);
+    }
+
+    public void run() {
+        getSequence();
+    }
+
+    public void getSequence( ){
+
+        boolean gotSequence = false ;
+
+        for ( int i = 0 ; i< sequenceServers.length; i++){
+
+            if ( gotSequence ) break ;
+
+            Das1Source ds = sequenceServers[i];
+            String url = ds.getUrl() ;
+            char lastChar = url.charAt(url.length()-1);
+            if ( ! (lastChar == '/') )
+                url +="/" ;
+            String dascmd = url + "sequence?segment=";
+            String connstr = dascmd + sp_accession ;
+
+            try {
+
+                String sequence = retrieveSequence(connstr);
+                // bug in aristotle das source?
+                sequence.replaceAll(" ","");
+                gotSequence = true ;
+                // set the sequence ...
+
+                triggerNewSequence(sp_accession,sequence);
+
+
+                return;
+            }
+            catch (Exception ex) {
+                ex.printStackTrace();
+                logger.warning(ex.getMessage());
+
+                //triggerException(ex);
+
+            }
+        }
+
+        logger.log(Level.WARNING,"could not retreive UniProt sequence from any available DAS sequence server");
+
+        triggerNoSequence(sp_accession);
+
+    }
+
+
+
+//    private void triggerException(Exception e){
+//        Iterator iter = seqListeners.iterator();
+//        while (iter.hasNext()){
+//           SequenceListener li = (SequenceListener)iter.next();
+//           li.exceptionOccured(e);
+//        }
+//    }
+
+    private void triggerNewSequence(String sp_accession,String sequence){
+
+        Iterator iter = seqListeners.iterator();
+        while (iter.hasNext()){
+           SequenceListener li = (SequenceListener)iter.next();
+            //SequenceEvent event = new SequenceEvent(sequence);
+           SequenceEvent event = new SequenceEvent(sp_accession,sequence);
+           li.newSequence(event);
+        }
+    }
+
+    private void triggerNoSequence(String ac){
+
+        Iterator iter = seqListeners.iterator();
+        while (iter.hasNext()){
+            SequenceListener li = (SequenceListener)iter.next();
+            li.noObjectFound(ac);
+        }
+
+    }
+
+    /** retrieve the Sequence from a DAS server.
+     *
+     * @param connstr - the DAS - request string. e.g. http://www.ebi.ac.uk/das-srv/uniprot/das/aristotle/sequence?segment=P00280
+     * @return the requested Sequence
+     * @throws Exception
+     */
+    public String retrieveSequence( String connstr)
+    throws Exception
+    {
+
+        //logger.finest("trying: " + connstr) ;
+        URL dasUrl = new URL(connstr);
+        //DAS_httpConnector dhtp = new DAS_httpConnector() ;
+        logger.info("requesting sequence from " + connstr);
+        InputStream dasInStream =open(dasUrl);
+
+
+        SAXParserFactory spfactory =
+            SAXParserFactory.newInstance();
+
+       // never do this
+        //String vali = System.getProperty("XMLVALIDATION");
+        String vali = "false";
+        boolean validate = false ;
+        if ((vali != null) && ( vali.equals("true")) )
+            validate = true ;
+        spfactory.setValidating(validate);
+
+        SAXParser saxParser = null ;
+
+        try{
+            saxParser =
+                spfactory.newSAXParser();
+        } catch (ParserConfigurationException e) {
+            //e.printStackTrace();
+            logger.log(Level.FINER,"Uncaught exception", e);
+        }
+
+        XMLReader xmlreader = saxParser.getXMLReader();
+
+        try {
+            xmlreader.setFeature("http://xml.org/sax/features/validation", validate);
+        } catch (SAXException e) {
+            logger.finer("Cannot set validation to " + validate);
+            logger.log(Level.FINER,"Uncaught exception", e);
+        }
+
+        try {
+            xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",validate);
+        } catch (SAXNotRecognizedException e){
+            //e.printStackTrace();
+            logger.finer("Cannot set load-external-dtd to" + validate);
+            logger.log(Level.FINER,"Uncaught exception", e);
+            //System.err.println("Cannot set load-external-dtd to" + validate);
+        }
+
+
+        //DAS_DNA_Handler cont_handle = new DAS_DNA_Handler() ;
+        DAS_Sequence_Handler cont_handle = new DAS_Sequence_Handler() ;
+        xmlreader.setContentHandler(cont_handle);
+        xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+        InputSource insource = new InputSource() ;
+        insource.setByteStream(dasInStream);
+
+        xmlreader.parse(insource);
+        String sequence = cont_handle.get_sequence();
+        //logger.finest("Got sequence from DAS: " +sequence);
+        logger.exiting(this.getClass().getName(), "retreiveSequence",  sequence);
+        return sequence ;
+    }
+
+    private InputStream open(URL url) {
+        {
+
+            InputStream inStream = null;
+            try{
+
+
+
+
+                HttpURLConnection huc = null;
+
+                huc = DAS_FeatureRetrieve.openHttpURLConnection(url);
+
+
+                logger.finest(huc.getResponseMessage());
+
+                inStream = huc.getInputStream();
+
+
+            }
+            catch ( Exception ex){
+                ex.printStackTrace();
+                logger.log(Level.WARNING,"exception occured", ex);
+            }
+
+            return inStream;
+        }
+
+    }
+
+}
diff --git a/src/org/biojava/dasobert/das/SpiceDasSource.java b/src/org/biojava/dasobert/das/SpiceDasSource.java
new file mode 100755 (executable)
index 0000000..a903af3
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 17.10.2004
+ * @author Andreas Prlic
+ *
+ */
+
+package org.biojava.dasobert.das ;
+
+//import org.biojava.services.das.registry.*;
+import org.biojava.dasobert.das.DAS_StylesheetRetrieve;
+import org.biojava.dasobert.dasregistry.Das1Source;
+import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
+import org.biojava.dasobert.dasregistry.DasSource;
+import java.io.IOException                ;
+import java.text.DateFormat               ;
+import java.text.SimpleDateFormat         ;
+import java.util.*;
+
+
+import java.net.URL;
+
+/** Manages all data about a DAS source that SPICE requires */
+public class SpiceDasSource
+extends Das1Source
+
+{
+
+
+    boolean status ;
+    boolean registered ; // a flag to trace if source comes from registry or from user vonfig
+    Map[] typeStyles;
+    Map[] threeDstyles;
+    public static String DEFAULT_NICKNAME = "MyDASsource";
+    public static String DEFAULT_CAPABILITY = "features";
+    public SpiceDasSource() {
+        super();
+
+        status    = true ;  // default source is actived and used .
+        registered = true ; // default true = source comes from registry
+        setNickname(DEFAULT_NICKNAME);
+        typeStyles = null;
+        threeDstyles = null;
+        String[] caps = new String[1];
+        caps[0] = DEFAULT_CAPABILITY;
+        setCapabilities(caps);
+    }
+
+    public void loadStylesheet(){
+        DAS_StylesheetRetrieve dsr = new DAS_StylesheetRetrieve();
+        String cmd = getUrl()+"stylesheet";
+        URL url = null;
+        try {
+            url = new URL(cmd);
+        } catch (Exception e){
+            e.printStackTrace();
+            return ;
+        }
+        Map[] styles = dsr.retrieve(url);
+
+        if ( styles != null){
+            typeStyles = styles;
+        } else {
+            typeStyles = new Map[0];
+        }
+
+
+        Map[] t3dStyles = dsr.get3DStyle();
+        if ( t3dStyles != null){
+            threeDstyles = t3dStyles;
+        } else {
+            threeDstyles = new Map[0];
+        }
+    }
+
+    /** returns the Stylesheet that is provided by a DAS source.
+     * It provides info of how to draw a particular feature.
+     * returns null if not attempt has been made to load the stylesheet.
+     * afterwards it returns a Map[0] or the Map[] containing the style data.
+     *
+     * @return
+     */
+    public Map[] getStylesheet(){
+        return typeStyles;
+    }
+
+    /** get the stylesheet containing the instructions how to paint in 3D.
+     *
+     * @return
+     */
+    public Map[] get3DStylesheet(){
+        return threeDstyles;
+    }
+
+    /** a flag if this das source is active
+     * or
+     * @param flag
+     */
+    public void    setStatus(boolean flag) { status = flag ; }
+    public boolean getStatus()             { return status ; }
+
+    public void    setRegistered(boolean flag) { registered = flag ; }
+    public boolean getRegistered()             { return registered ; }
+
+
+    /** convert DasSource to SpiceDasSource */
+    public static SpiceDasSource  fromDasSource(DasSource ds) {
+        SpiceDasSource s = new SpiceDasSource();
+        s.setUrl(ds.getUrl());
+        s.setAdminemail(ds.getAdminemail());
+        s.setDescription(ds.getDescription());
+        s.setCoordinateSystem(ds.getCoordinateSystem());
+        s.setCapabilities(ds.getCapabilities());
+        s.setRegisterDate(ds.getRegisterDate());
+        s.setLeaseDate(ds.getLeaseDate());
+        s.setNickname(ds.getNickname());
+
+
+        // testcode now part of coordinate system...
+        //s.setTestCode(ds.getTestCode());
+        s.setId(ds.getId());
+        s.setLabels(ds.getLabels());
+        s.setHelperurl(ds.getHelperurl());
+        return s;
+    }
+
+
+    public String toString() {
+        String txt = getId()  + " " + getNickname() + " " + getUrl() ;
+        return txt;
+    }
+
+
+}
diff --git a/src/org/biojava/dasobert/das/Xpm.java b/src/org/biojava/dasobert/das/Xpm.java
new file mode 100755 (executable)
index 0000000..0ebd92d
--- /dev/null
@@ -0,0 +1,1903 @@
+//@(#) Xpm.java 1.9@(#)
+//Copyright (c) 2001, Phil Brown, phil@bolthole.com
+//licensed under GNU LGPL version 2
+
+/* A library class to convert Xpm data into an image.
+ * It also has nice little utilities like converting
+ * color NAMES to rgb values (based on X11 rgb.txt)
+ *
+ * Note1: There might be a slight conflict of copyright,
+ *  If the rgb.txt data from the X11 distribution has nasty copyright
+ *  stuff attached to it. If so... my apologies to the X11 folk.
+ *
+ * This is an improved version, that is not hardcoded so much for
+ * "crossfire". It should hopefully handle all xpm types.
+ * If it doesnt, please send me email, with a sample xpm image
+ * that it fails under, and I'll try to fix it.
+ */
+package org.biojava.dasobert.das;
+
+
+import java.awt.Image;
+import java.util.Hashtable;
+import java.awt.Toolkit;
+import java.awt.image.*;
+
+//rgb data originally from
+//! $XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp $
+
+
+
+//Note: This class is huge, and has icky large static initializers.
+//They are also ARRAY-based, which means poor lookup speed.
+//While that is kinda annoying, it shouldn't be TOO bad.
+//And it should greatly improve STARTUP time, which I consider
+//at this point to be more important
+
+public class Xpm
+{
+    static String VersionString="Phil@bolthole.com Xpm v1.1";
+    static final int rgbents[][] = {
+            {255, 250, 250},
+            {248, 248, 255},
+            {248, 248, 255},
+            {245, 245, 245},
+            {245, 245, 245},
+            {220, 220, 220},
+            {255, 250, 240},
+            {255, 250, 240},
+            {253, 245, 230},
+            {253, 245, 230},
+            {250, 240, 230},
+            {250, 235, 215},
+            {250, 235, 215},
+            {255, 239, 213},
+            {255, 239, 213},
+            {255, 235, 205},
+            {255, 235, 205},
+            {255, 228, 196},
+            {255, 218, 185},
+            {255, 218, 185},
+            {255, 222, 173},
+            {255, 222, 173},
+            {255, 228, 181},
+            {255, 248, 220},
+            {255, 255, 240},
+            {255, 250, 205},
+            {255, 250, 205},
+            {255, 245, 238},
+            {240, 255, 240},
+            {245, 255, 250},
+            {245, 255, 250},
+            {240, 255, 255},
+            {240, 248, 255},
+            {240, 248, 255},
+            {230, 230, 250},
+            {255, 240, 245},
+            {255, 240, 245},
+            {255, 228, 225},
+            {255, 228, 225},
+            {255, 255, 255},
+            {  0,   0,   0},
+            { 47,  79,  79},
+            { 47,  79,  79},
+            { 47,  79,  79},
+            { 47,  79,  79},
+            {105, 105, 105},
+            {105, 105, 105},
+            {105, 105, 105},
+            {105, 105, 105},
+            {112, 128, 144},
+            {112, 128, 144},
+            {112, 128, 144},
+            {112, 128, 144},
+            {119, 136, 153},
+            {119, 136, 153},
+            {119, 136, 153},
+            {119, 136, 153},
+            {190, 190, 190},
+            {190, 190, 190},
+            {211, 211, 211},
+            {211, 211, 211},
+            {211, 211, 211},
+            {211, 211, 211},
+            { 25,  25, 112},
+            { 25,  25, 112},
+            {  0,   0, 128},
+            {  0,   0, 128},
+            {  0,   0, 128},
+            {100, 149, 237},
+            {100, 149, 237},
+            { 72,  61, 139},
+            { 72,  61, 139},
+            {106,  90, 205},
+            {106,  90, 205},
+            {123, 104, 238},
+            {123, 104, 238},
+            {132, 112, 255},
+            {132, 112, 255},
+            {  0,   0, 205},
+            {  0,   0, 205},
+            { 65, 105, 225},
+            { 65, 105, 225},
+            {  0,   0, 255},
+            { 30, 144, 255},
+            { 30, 144, 255},
+            {  0, 191, 255},
+            {  0, 191, 255},
+            {135, 206, 235},
+            {135, 206, 235},
+            {135, 206, 250},
+            {135, 206, 250},
+            { 70, 130, 180},
+            { 70, 130, 180},
+            {176, 196, 222},
+            {176, 196, 222},
+            {173, 216, 230},
+            {173, 216, 230},
+            {176, 224, 230},
+            {176, 224, 230},
+            {175, 238, 238},
+            {175, 238, 238},
+            {  0, 206, 209},
+            {  0, 206, 209},
+            { 72, 209, 204},
+            { 72, 209, 204},
+            { 64, 224, 208},
+            {  0, 255, 255},
+            {224, 255, 255},
+            {224, 255, 255},
+            { 95, 158, 160},
+            { 95, 158, 160},
+            {102, 205, 170},
+            {102, 205, 170},
+            {127, 255, 212},
+            {  0, 100,   0},
+            {  0, 100,   0},
+            { 85, 107,  47},
+            { 85, 107,  47},
+            {143, 188, 143},
+            {143, 188, 143},
+            { 46, 139,  87},
+            { 46, 139,  87},
+            { 60, 179, 113},
+            { 60, 179, 113},
+            { 32, 178, 170},
+            { 32, 178, 170},
+            {152, 251, 152},
+            {152, 251, 152},
+            {  0, 255, 127},
+            {  0, 255, 127},
+            {124, 252,   0},
+            {124, 252,   0},
+            {  0, 255,   0},
+            {127, 255,   0},
+            {  0, 250, 154},
+            {  0, 250, 154},
+            {173, 255,  47},
+            {173, 255,  47},
+            { 50, 205,  50},
+            { 50, 205,  50},
+            {154, 205,  50},
+            {154, 205,  50},
+            { 34, 139,  34},
+            { 34, 139,  34},
+            {107, 142,  35},
+            {107, 142,  35},
+            {189, 183, 107},
+            {189, 183, 107},
+            {240, 230, 140},
+            {238, 232, 170},
+            {238, 232, 170},
+            {250, 250, 210},
+            {250, 250, 210},
+            {255, 255, 224},
+            {255, 255, 224},
+            {255, 255,   0},
+            {255, 215,   0},
+            {238, 221, 130},
+            {238, 221, 130},
+            {218, 165,  32},
+            {184, 134,  11},
+            {184, 134,  11},
+            {188, 143, 143},
+            {188, 143, 143},
+            {205,  92,  92},
+            {205,  92,  92},
+            {139,  69,  19},
+            {139,  69,  19},
+            {160,  82,  45},
+            {205, 133,  63},
+            {222, 184, 135},
+            {245, 245, 220},
+            {245, 222, 179},
+            {244, 164,  96},
+            {244, 164,  96},
+            {210, 180, 140},
+            {210, 105,  30},
+            {178,  34,  34},
+            {165,  42,  42},
+            {233, 150, 122},
+            {233, 150, 122},
+            {250, 128, 114},
+            {255, 160, 122},
+            {255, 160, 122},
+            {255, 165,   0},
+            {255, 140,   0},
+            {255, 140,   0},
+            {255, 127,  80},
+            {240, 128, 128},
+            {240, 128, 128},
+            {255,  99,  71},
+            {255,  69,   0},
+            {255,  69,   0},
+            {255,   0,   0},
+            {255, 105, 180},
+            {255, 105, 180},
+            {255,  20, 147},
+            {255,  20, 147},
+            {255, 192, 203},
+            {255, 182, 193},
+            {255, 182, 193},
+            {219, 112, 147},
+            {219, 112, 147},
+            {176,  48,  96},
+            {199,  21, 133},
+            {199,  21, 133},
+            {208,  32, 144},
+            {208,  32, 144},
+            {255,   0, 255},
+            {238, 130, 238},
+            {221, 160, 221},
+            {218, 112, 214},
+            {186,  85, 211},
+            {186,  85, 211},
+            {153,  50, 204},
+            {153,  50, 204},
+            {148,   0, 211},
+            {148,   0, 211},
+            {138,  43, 226},
+            {138,  43, 226},
+            {160,  32, 240},
+            {147, 112, 219},
+            {147, 112, 219},
+            {216, 191, 216},
+            {255, 250, 250},
+            {238, 233, 233},
+            {205, 201, 201},
+            {139, 137, 137},
+            {255, 245, 238},
+            {238, 229, 222},
+            {205, 197, 191},
+            {139, 134, 130},
+            {255, 239, 219},
+            {238, 223, 204},
+            {205, 192, 176},
+            {139, 131, 120},
+            {255, 228, 196},
+            {238, 213, 183},
+            {205, 183, 158},
+            {139, 125, 107},
+            {255, 218, 185},
+            {238, 203, 173},
+            {205, 175, 149},
+            {139, 119, 101},
+            {255, 222, 173},
+            {238, 207, 161},
+            {205, 179, 139},
+            {139, 121, 94},
+            {255, 250, 205},
+            {238, 233, 191},
+            {205, 201, 165},
+            {139, 137, 112},
+            {255, 248, 220},
+            {238, 232, 205},
+            {205, 200, 177},
+            {139, 136, 120},
+            {255, 255, 240},
+            {238, 238, 224},
+            {205, 205, 193},
+            {139, 139, 131},
+            {240, 255, 240},
+            {224, 238, 224},
+            {193, 205, 193},
+            {131, 139, 131},
+            {255, 240, 245},
+            {238, 224, 229},
+            {205, 193, 197},
+            {139, 131, 134},
+            {255, 228, 225},
+            {238, 213, 210},
+            {205, 183, 181},
+            {139, 125, 123},
+            {240, 255, 255},
+            {224, 238, 238},
+            {193, 205, 205},
+            {131, 139, 139},
+            {131, 111, 255},
+            {122, 103, 238},
+            {105,  89, 205},
+            { 71,  60, 139},
+            { 72, 118, 255},
+            { 67, 110, 238},
+            { 58,  95, 205},
+            { 39,  64, 139},
+            {  0,   0, 255},
+            {  0,   0, 238},
+            {  0,   0, 205},
+            {  0,   0, 139},
+            { 30, 144, 255},
+            { 28, 134, 238},
+            { 24, 116, 205},
+            { 16,  78, 139},
+            { 99, 184, 255},
+            { 92, 172, 238},
+            { 79, 148, 205},
+            { 54, 100, 139},
+            {  0, 191, 255},
+            {  0, 178, 238},
+            {  0, 154, 205},
+            {  0, 104, 139},
+            {135, 206, 255},
+            {126, 192, 238},
+            {108, 166, 205},
+            { 74, 112, 139},
+            {176, 226, 255},
+            {164, 211, 238},
+            {141, 182, 205},
+            { 96, 123, 139},
+            {198, 226, 255},
+            {185, 211, 238},
+            {159, 182, 205},
+            {108, 123, 139},
+            {202, 225, 255},
+            {188, 210, 238},
+            {162, 181, 205},
+            {110, 123, 139},
+            {191, 239, 255},
+            {178, 223, 238},
+            {154, 192, 205},
+            {104, 131, 139},
+            {224, 255, 255},
+            {209, 238, 238},
+            {180, 205, 205},
+            {122, 139, 139},
+            {187, 255, 255},
+            {174, 238, 238},
+            {150, 205, 205},
+            {102, 139, 139},
+            {152, 245, 255},
+            {142, 229, 238},
+            {122, 197, 205},
+            { 83, 134, 139},
+            {  0, 245, 255},
+            {  0, 229, 238},
+            {  0, 197, 205},
+            {  0, 134, 139},
+            {  0, 255, 255},
+            {  0, 238, 238},
+            {  0, 205, 205},
+            {  0, 139, 139},
+            {151, 255, 255},
+            {141, 238, 238},
+            {121, 205, 205},
+            { 82, 139, 139},
+            {127, 255, 212},
+            {118, 238, 198},
+            {102, 205, 170},
+            { 69, 139, 116},
+            {193, 255, 193},
+            {180, 238, 180},
+            {155, 205, 155},
+            {105, 139, 105},
+            { 84, 255, 159},
+            { 78, 238, 148},
+            { 67, 205, 128},
+            { 46, 139, 87},
+            {154, 255, 154},
+            {144, 238, 144},
+            {124, 205, 124},
+            { 84, 139, 84},
+            {  0, 255, 127},
+            {  0, 238, 118},
+            {  0, 205, 102},
+            {  0, 139, 69},
+            {  0, 255,  0},
+            {  0, 238,  0},
+            {  0, 205,  0},
+            {  0, 139,  0},
+            {127, 255,  0},
+            {118, 238,  0},
+            {102, 205,  0},
+            { 69, 139,  0},
+            {192, 255, 62},
+            {179, 238, 58},
+            {154, 205, 50},
+            {105, 139, 34},
+            {202, 255, 112},
+            {188, 238, 104},
+            {162, 205, 90},
+            {110, 139, 61},
+            {255, 246, 143},
+            {238, 230, 133},
+            {205, 198, 115},
+            {139, 134, 78},
+            {255, 236, 139},
+            {238, 220, 130},
+            {205, 190, 112},
+            {139, 129, 76},
+            {255, 255, 224},
+            {238, 238, 209},
+            {205, 205, 180},
+            {139, 139, 122},
+            {255, 255,  0},
+            {238, 238,  0},
+            {205, 205,  0},
+            {139, 139,  0},
+            {255, 215,  0},
+            {238, 201,  0},
+            {205, 173,  0},
+            {139, 117,  0},
+            {255, 193, 37},
+            {238, 180, 34},
+            {205, 155, 29},
+            {139, 105, 20},
+            {255, 185, 15},
+            {238, 173, 14},
+            {205, 149, 12},
+            {139, 101,  8},
+            {255, 193, 193},
+            {238, 180, 180},
+            {205, 155, 155},
+            {139, 105, 105},
+            {255, 106, 106},
+            {238,  99, 99},
+            {205,  85, 85},
+            {139,  58, 58},
+            {255, 130, 71},
+            {238, 121, 66},
+            {205, 104, 57},
+            {139,  71, 38},
+            {255, 211, 155},
+            {238, 197, 145},
+            {205, 170, 125},
+            {139, 115, 85},
+            {255, 231, 186},
+            {238, 216, 174},
+            {205, 186, 150},
+            {139, 126, 102},
+            {255, 165, 79},
+            {238, 154, 73},
+            {205, 133, 63},
+            {139,  90, 43},
+            {255, 127, 36},
+            {238, 118, 33},
+            {205, 102, 29},
+            {139,  69, 19},
+            {255,  48, 48},
+            {238,  44, 44},
+            {205,  38, 38},
+            {139,  26, 26},
+            {255,  64, 64},
+            {238,  59, 59},
+            {205,  51, 51},
+            {139,  35, 35},
+            {255, 140, 105},
+            {238, 130,  98},
+            {205, 112,  84},
+            {139,  76,  57},
+            {255, 160, 122},
+            {238, 149, 114},
+            {205, 129,  98},
+            {139,  87,  66},
+            {255, 165,   0},
+            {238, 154,   0},
+            {205, 133,   0},
+            {139,  90,   0},
+            {255, 127,   0},
+            {238, 118,   0},
+            {205, 102,   0},
+            {139,  69,   0},
+            {255, 114,  86},
+            {238, 106,  80},
+            {205,  91,  69},
+            {139,  62,  47},
+            {255,  99,  71},
+            {238,  92,  66},
+            {205,  79,  57},
+            {139,  54,  38},
+            {255,  69,   0},
+            {238,  64,   0},
+            {205,  55,   0},
+            {139,  37,   0},
+            {255,   0,   0},
+            {238,   0,   0},
+            {205,   0,   0},
+            {139,   0,   0},
+            {255,  20, 147},
+            {238,  18, 137},
+            {205,  16, 118},
+            {139,  10,  80},
+            {255, 110, 180},
+            {238, 106, 167},
+            {205,  96, 144},
+            {139,  58,  98},
+            {255, 181, 197},
+            {238, 169, 184},
+            {205, 145, 158},
+            {139,  99, 108},
+            {255, 174, 185},
+            {238, 162, 173},
+            {205, 140, 149},
+            {139,  95, 101},
+            {255, 130, 171},
+            {238, 121, 159},
+            {205, 104, 137},
+            {139,  71,  93},
+            {255,  52, 179},
+            {238,  48, 167},
+            {205,  41, 144},
+            {139,  28,  98},
+            {255,  62, 150},
+            {238,  58, 140},
+            {205,  50, 120},
+            {139,  34,  82},
+            {255,   0, 255},
+            {238,   0, 238},
+            {205,   0, 205},
+            {139,   0, 139},
+            {255, 131, 250},
+            {238, 122, 233},
+            {205, 105, 201},
+            {139,  71, 137},
+            {255, 187, 255},
+            {238, 174, 238},
+            {205, 150, 205},
+            {139, 102, 139},
+            {224, 102, 255},
+            {209,  95, 238},
+            {180,  82, 205},
+            {122,  55, 139},
+            {191,  62, 255},
+            {178,  58, 238},
+            {154,  50, 205},
+            {104,  34, 139},
+            {155,  48, 255},
+            {145,  44, 238},
+            {125,  38, 205},
+            { 85,  26, 139},
+            {171, 130, 255},
+            {159, 121, 238},
+            {137, 104, 205},
+            { 93,  71, 139},
+            {255, 225, 255},
+            {238, 210, 238},
+            {205, 181, 205},
+            {139, 123, 139},
+            {  0,   0,   0},
+            {  0,   0,   0},
+            {  3,   3,   3},
+            {  3,   3,   3},
+            {  5,   5,   5},
+            {  5,   5,   5},
+            {  8,   8,   8},
+            {  8,   8,   8},
+            { 10,  10,  10},
+            { 10,  10,  10},
+            { 13,  13,  13},
+            { 13,  13,  13},
+            { 15,  15,  15},
+            { 15,  15,  15},
+            { 18,  18,  18},
+            { 18,  18,  18},
+            { 20,  20,  20},
+            { 20,  20,  20},
+            { 23,  23,  23},
+            { 23,  23,  23},
+            { 26,  26,  26},
+            { 26,  26,  26},
+            { 28,  28,  28},
+            { 28,  28,  28},
+            { 31,  31,  31},
+            { 31,  31,  31},
+            { 33,  33,  33},
+            { 33,  33,  33},
+            { 36,  36,  36},
+            { 36,  36,  36},
+            { 38,  38,  38},
+            { 38,  38,  38},
+            { 41,  41,  41},
+            { 41,  41,  41},
+            { 43,  43,  43},
+            { 43,  43,  43},
+            { 46,  46,  46},
+            { 46,  46,  46},
+            { 48,  48,  48},
+            { 48,  48,  48},
+            { 51,  51,  51},
+            { 51,  51,  51},
+            { 54,  54,  54},
+            { 54,  54,  54},
+            { 56,  56,  56},
+            { 56,  56,  56},
+            { 59,  59,  59},
+            { 59,  59,  59},
+            { 61,  61,  61},
+            { 61,  61,  61},
+            { 64,  64,  64},
+            { 64,  64,  64},
+            { 66,  66,  66},
+            { 66,  66,  66},
+            { 69,  69,  69},
+            { 69,  69,  69},
+            { 71,  71,  71},
+            { 71,  71,  71},
+            { 74,  74,  74},
+            { 74,  74,  74},
+            { 77,  77,  77},
+            { 77,  77,  77},
+            { 79,  79,  79},
+            { 79,  79,  79},
+            { 82,  82,  82},
+            { 82,  82,  82},
+            { 84,  84,  84},
+            { 84,  84,  84},
+            { 87,  87,  87},
+            { 87,  87,  87},
+            { 89,  89,  89},
+            { 89,  89,  89},
+            { 92,  92,  92},
+            { 92,  92,  92},
+            { 94,  94,  94},
+            { 94,  94,  94},
+            { 97,  97,  97},
+            { 97,  97,  97},
+            { 99,  99,  99},
+            { 99,  99,  99},
+            {102, 102, 102},
+            {102, 102, 102},
+            {105, 105, 105},
+            {105, 105, 105},
+            {107, 107, 107},
+            {107, 107, 107},
+            {110, 110, 110},
+            {110, 110, 110},
+            {112, 112, 112},
+            {112, 112, 112},
+            {115, 115, 115},
+            {115, 115, 115},
+            {117, 117, 117},
+            {117, 117, 117},
+            {120, 120, 120},
+            {120, 120, 120},
+            {122, 122, 122},
+            {122, 122, 122},
+            {125, 125, 125},
+            {125, 125, 125},
+            {127, 127, 127},
+            {127, 127, 127},
+            {130, 130, 130},
+            {130, 130, 130},
+            {133, 133, 133},
+            {133, 133, 133},
+            {135, 135, 135},
+            {135, 135, 135},
+            {138, 138, 138},
+            {138, 138, 138},
+            {140, 140, 140},
+            {140, 140, 140},
+            {143, 143, 143},
+            {143, 143, 143},
+            {145, 145, 145},
+            {145, 145, 145},
+            {148, 148, 148},
+            {148, 148, 148},
+            {150, 150, 150},
+            {150, 150, 150},
+            {153, 153, 153},
+            {153, 153, 153},
+            {156, 156, 156},
+            {156, 156, 156},
+            {158, 158, 158},
+            {158, 158, 158},
+            {161, 161, 161},
+            {161, 161, 161},
+            {163, 163, 163},
+            {163, 163, 163},
+            {166, 166, 166},
+            {166, 166, 166},
+            {168, 168, 168},
+            {168, 168, 168},
+            {171, 171, 171},
+            {171, 171, 171},
+            {173, 173, 173},
+            {173, 173, 173},
+            {176, 176, 176},
+            {176, 176, 176},
+            {179, 179, 179},
+            {179, 179, 179},
+            {181, 181, 181},
+            {181, 181, 181},
+            {184, 184, 184},
+            {184, 184, 184},
+            {186, 186, 186},
+            {186, 186, 186},
+            {189, 189, 189},
+            {189, 189, 189},
+            {191, 191, 191},
+            {191, 191, 191},
+            {194, 194, 194},
+            {194, 194, 194},
+            {196, 196, 196},
+            {196, 196, 196},
+            {199, 199, 199},
+            {199, 199, 199},
+            {201, 201, 201},
+            {201, 201, 201},
+            {204, 204, 204},
+            {204, 204, 204},
+            {207, 207, 207},
+            {207, 207, 207},
+            {209, 209, 209},
+            {209, 209, 209},
+            {212, 212, 212},
+            {212, 212, 212},
+            {214, 214, 214},
+            {214, 214, 214},
+            {217, 217, 217},
+            {217, 217, 217},
+            {219, 219, 219},
+            {219, 219, 219},
+            {222, 222, 222},
+            {222, 222, 222},
+            {224, 224, 224},
+            {224, 224, 224},
+            {227, 227, 227},
+            {227, 227, 227},
+            {229, 229, 229},
+            {229, 229, 229},
+            {232, 232, 232},
+            {232, 232, 232},
+            {235, 235, 235},
+            {235, 235, 235},
+            {237, 237, 237},
+            {237, 237, 237},
+            {240, 240, 240},
+            {240, 240, 240},
+            {242, 242, 242},
+            {242, 242, 242},
+            {245, 245, 245},
+            {245, 245, 245},
+            {247, 247, 247},
+            {247, 247, 247},
+            {250, 250, 250},
+            {250, 250, 250},
+            {252, 252, 252},
+            {252, 252, 252},
+            {255, 255, 255},
+            {255, 255, 255},
+            {169, 169, 169},
+            {169, 169, 169},
+            {169, 169, 169},
+            {169, 169, 169},
+            {0,     0, 139},
+            {0,     0, 139},
+            {0,   139, 139},
+            {0,   139, 139},
+            {139,   0, 139},
+            {139,   0, 139},
+            {139,   0,   0},
+            {139,   0,   0},
+            {144, 238, 144},
+            {144, 238, 144}
+    };
+    
+    static String rgbnames[] = {
+            "snow",
+            "ghost white",
+            "GhostWhite",
+            "white smoke",
+            "WhiteSmoke",
+            "gainsboro",
+            "floral white",
+            "FloralWhite",
+            "old lace",
+            "OldLace",
+            "linen",
+            "antique white",
+            "AntiqueWhite",
+            "papaya whip",
+            "PapayaWhip",
+            "blanched almond",
+            "BlanchedAlmond",
+            "bisque",
+            "peach puff",
+            "PeachPuff",
+            "navajo white",
+            "NavajoWhite",
+            "moccasin",
+            "cornsilk",
+            "ivory",
+            "lemon chiffon",
+            "LemonChiffon",
+            "seashell",
+            "honeydew",
+            "mint cream",
+            "MintCream",
+            "azure",
+            "alice blue",
+            "AliceBlue",
+            "lavender",
+            "lavender blush",
+            "LavenderBlush",
+            "misty rose",
+            "MistyRose",
+            "white",
+            "black",
+            "dark slate gray",
+            "DarkSlateGray",
+            "dark slate grey",
+            "DarkSlateGrey",
+            "dim gray",
+            "DimGray",
+            "dim grey",
+            "DimGrey",
+            "slate gray",
+            "SlateGray",
+            "slate grey",
+            "SlateGrey",
+            "light slate gray",
+            "LightSlateGray",
+            "light slate grey",
+            "LightSlateGrey",
+            "gray",
+            "grey",
+            "light grey",
+            "LightGrey",
+            "light gray",
+            "LightGray",
+            "midnight blue",
+            "MidnightBlue",
+            "navy",
+            "navy blue",
+            "NavyBlue",
+            "cornflower blue",
+            "CornflowerBlue",
+            "dark slate blue",
+            "DarkSlateBlue",
+            "slate blue",
+            "SlateBlue",
+            "medium slate blue",
+            "MediumSlateBlue",
+            "light slate blue",
+            "LightSlateBlue",
+            "medium blue",
+            "MediumBlue",
+            "royal blue",
+            "RoyalBlue",
+            "blue",
+            "dodger blue",
+            "DodgerBlue",
+            "deep sky blue",
+            "DeepSkyBlue",
+            "sky blue",
+            "SkyBlue",
+            "light sky blue",
+            "LightSkyBlue",
+            "steel blue",
+            "SteelBlue",
+            "light steel blue",
+            "LightSteelBlue",
+            "light blue",
+            "LightBlue",
+            "powder blue",
+            "PowderBlue",
+            "pale turquoise",
+            "PaleTurquoise",
+            "dark turquoise",
+            "DarkTurquoise",
+            "medium turquoise",
+            "MediumTurquoise",
+            "turquoise",
+            "cyan",
+            "light cyan",
+            "LightCyan",
+            "cadet blue",
+            "CadetBlue",
+            "medium aquamarine",
+            "MediumAquamarine",
+            "aquamarine",
+            "dark green",
+            "DarkGreen",
+            "dark olive green",
+            "DarkOliveGreen",
+            "dark sea green",
+            "DarkSeaGreen",
+            "sea green",
+            "SeaGreen",
+            "medium sea green",
+            "MediumSeaGreen",
+            "light sea green",
+            "LightSeaGreen",
+            "pale green",
+            "PaleGreen",
+            "spring green",
+            "SpringGreen",
+            "lawn green",
+            "LawnGreen",
+            "green",
+            "chartreuse",
+            "medium spring green",
+            "MediumSpringGreen",
+            "green yellow",
+            "GreenYellow",
+            "lime green",
+            "LimeGreen",
+            "yellow green",
+            "YellowGreen",
+            "forest green",
+            "ForestGreen",
+            "olive drab",
+            "OliveDrab",
+            "dark khaki",
+            "DarkKhaki",
+            "khaki",
+            "pale goldenrod",
+            "PaleGoldenrod",
+            "light goldenrod yellow",
+            "LightGoldenrodYellow",
+            "light yellow",
+            "LightYellow",
+            "yellow",
+            "gold",
+            "light goldenrod",
+            "LightGoldenrod",
+            "goldenrod",
+            "dark goldenrod",
+            "DarkGoldenrod",
+            "rosy brown",
+            "RosyBrown",
+            "indian red",
+            "IndianRed",
+            "saddle brown",
+            "SaddleBrown",
+            "sienna",
+            "peru",
+            "burlywood",
+            "beige",
+            "wheat",
+            "sandy brown",
+            "SandyBrown",
+            "tan",
+            "chocolate",
+            "firebrick",
+            "brown",
+            "dark salmon",
+            "DarkSalmon",
+            "salmon",
+            "light salmon",
+            "LightSalmon",
+            "orange",
+            "dark orange",
+            "DarkOrange",
+            "coral",
+            "light coral",
+            "LightCoral",
+            "tomato",
+            "orange red",
+            "OrangeRed",
+            "red",
+            "hot pink",
+            "HotPink",
+            "deep pink",
+            "DeepPink",
+            "pink",
+            "light pink",
+            "LightPink",
+            "pale violet red",
+            "PaleVioletRed",
+            "maroon",
+            "medium violet red",
+            "MediumVioletRed",
+            "violet red",
+            "VioletRed",
+            "magenta",
+            "violet",
+            "plum",
+            "orchid",
+            "medium orchid",
+            "MediumOrchid",
+            "dark orchid",
+            "DarkOrchid",
+            "dark violet",
+            "DarkViolet",
+            "blue violet",
+            "BlueViolet",
+            "purple",
+            "medium purple",
+            "MediumPurple",
+            "thistle",
+            "snow1",
+            "snow2",
+            "snow3",
+            "snow4",
+            "seashell1",
+            "seashell2",
+            "seashell3",
+            "seashell4",
+            "AntiqueWhite1",
+            "AntiqueWhite2",
+            "AntiqueWhite3",
+            "AntiqueWhite4",
+            "bisque1",
+            "bisque2",
+            "bisque3",
+            "bisque4",
+            "PeachPuff1",
+            "PeachPuff2",
+            "PeachPuff3",
+            "PeachPuff4",
+            "NavajoWhite1",
+            "NavajoWhite2",
+            "NavajoWhite3",
+            "NavajoWhite4",
+            "LemonChiffon1",
+            "LemonChiffon2",
+            "LemonChiffon3",
+            "LemonChiffon4",
+            "cornsilk1",
+            "cornsilk2",
+            "cornsilk3",
+            "cornsilk4",
+            "ivory1",
+            "ivory2",
+            "ivory3",
+            "ivory4",
+            "honeydew1",
+            "honeydew2",
+            "honeydew3",
+            "honeydew4",
+            "LavenderBlush1",
+            "LavenderBlush2",
+            "LavenderBlush3",
+            "LavenderBlush4",
+            "MistyRose1",
+            "MistyRose2",
+            "MistyRose3",
+            "MistyRose4",
+            "azure1",
+            "azure2",
+            "azure3",
+            "azure4",
+            "SlateBlue1",
+            "SlateBlue2",
+            "SlateBlue3",
+            "SlateBlue4",
+            "RoyalBlue1",
+            "RoyalBlue2",
+            "RoyalBlue3",
+            "RoyalBlue4",
+            "blue1",
+            "blue2",
+            "blue3",
+            "blue4",
+            "DodgerBlue1",
+            "DodgerBlue2",
+            "DodgerBlue3",
+            "DodgerBlue4",
+            "SteelBlue1",
+            "SteelBlue2",
+            "SteelBlue3",
+            "SteelBlue4",
+            "DeepSkyBlue1",
+            "DeepSkyBlue2",
+            "DeepSkyBlue3",
+            "DeepSkyBlue4",
+            "SkyBlue1",
+            "SkyBlue2",
+            "SkyBlue3",
+            "SkyBlue4",
+            "LightSkyBlue1",
+            "LightSkyBlue2",
+            "LightSkyBlue3",
+            "LightSkyBlue4",
+            "SlateGray1",
+            "SlateGray2",
+            "SlateGray3",
+            "SlateGray4",
+            "LightSteelBlue1",
+            "LightSteelBlue2",
+            "LightSteelBlue3",
+            "LightSteelBlue4",
+            "LightBlue1",
+            "LightBlue2",
+            "LightBlue3",
+            "LightBlue4",
+            "LightCyan1",
+            "LightCyan2",
+            "LightCyan3",
+            "LightCyan4",
+            "PaleTurquoise1",
+            "PaleTurquoise2",
+            "PaleTurquoise3",
+            "PaleTurquoise4",
+            "CadetBlue1",
+            "CadetBlue2",
+            "CadetBlue3",
+            "CadetBlue4",
+            "turquoise1",
+            "turquoise2",
+            "turquoise3",
+            "turquoise4",
+            "cyan1",
+            "cyan2",
+            "cyan3",
+            "cyan4",
+            "DarkSlateGray1",
+            "DarkSlateGray2",
+            "DarkSlateGray3",
+            "DarkSlateGray4",
+            "aquamarine1",
+            "aquamarine2",
+            "aquamarine3",
+            "aquamarine4",
+            "DarkSeaGreen1",
+            "DarkSeaGreen2",
+            "DarkSeaGreen3",
+            "DarkSeaGreen4",
+            "SeaGreen1",
+            "SeaGreen2",
+            "SeaGreen3",
+            "SeaGreen4",
+            "PaleGreen1",
+            "PaleGreen2",
+            "PaleGreen3",
+            "PaleGreen4",
+            "SpringGreen1",
+            "SpringGreen2",
+            "SpringGreen3",
+            "SpringGreen4",
+            "green1",
+            "green2",
+            "green3",
+            "green4",
+            "chartreuse1",
+            "chartreuse2",
+            "chartreuse3",
+            "chartreuse4",
+            "OliveDrab1",
+            "OliveDrab2",
+            "OliveDrab3",
+            "OliveDrab4",
+            "DarkOliveGreen1",
+            "DarkOliveGreen2",
+            "DarkOliveGreen3",
+            "DarkOliveGreen4",
+            "khaki1",
+            "khaki2",
+            "khaki3",
+            "khaki4",
+            "LightGoldenrod1",
+            "LightGoldenrod2",
+            "LightGoldenrod3",
+            "LightGoldenrod4",
+            "LightYellow1",
+            "LightYellow2",
+            "LightYellow3",
+            "LightYellow4",
+            "yellow1",
+            "yellow2",
+            "yellow3",
+            "yellow4",
+            "gold1",
+            "gold2",
+            "gold3",
+            "gold4",
+            "goldenrod1",
+            "goldenrod2",
+            "goldenrod3",
+            "goldenrod4",
+            "DarkGoldenrod1",
+            "DarkGoldenrod2",
+            "DarkGoldenrod3",
+            "DarkGoldenrod4",
+            "RosyBrown1",
+            "RosyBrown2",
+            "RosyBrown3",
+            "RosyBrown4",
+            "IndianRed1",
+            "IndianRed2",
+            "IndianRed3",
+            "IndianRed4",
+            "sienna1",
+            "sienna2",
+            "sienna3",
+            "sienna4",
+            "burlywood1",
+            "burlywood2",
+            "burlywood3",
+            "burlywood4",
+            "wheat1",
+            "wheat2",
+            "wheat3",
+            "wheat4",
+            "tan1",
+            "tan2",
+            "tan3",
+            "tan4",
+            "chocolate1",
+            "chocolate2",
+            "chocolate3",
+            "chocolate4",
+            "firebrick1",
+            "firebrick2",
+            "firebrick3",
+            "firebrick4",
+            "brown1",
+            "brown2",
+            "brown3",
+            "brown4",
+            "salmon1",
+            "salmon2",
+            "salmon3",
+            "salmon4",
+            "LightSalmon1",
+            "LightSalmon2",
+            "LightSalmon3",
+            "LightSalmon4",
+            "orange1",
+            "orange2",
+            "orange3",
+            "orange4",
+            "DarkOrange1",
+            "DarkOrange2",
+            "DarkOrange3",
+            "DarkOrange4",
+            "coral1",
+            "coral2",
+            "coral3",
+            "coral4",
+            "tomato1",
+            "tomato2",
+            "tomato3",
+            "tomato4",
+            "OrangeRed1",
+            "OrangeRed2",
+            "OrangeRed3",
+            "OrangeRed4",
+            "red1",
+            "red2",
+            "red3",
+            "red4",
+            "DeepPink1",
+            "DeepPink2",
+            "DeepPink3",
+            "DeepPink4",
+            "HotPink1",
+            "HotPink2",
+            "HotPink3",
+            "HotPink4",
+            "pink1",
+            "pink2",
+            "pink3",
+            "pink4",
+            "LightPink1",
+            "LightPink2",
+            "LightPink3",
+            "LightPink4",
+            "PaleVioletRed1",
+            "PaleVioletRed2",
+            "PaleVioletRed3",
+            "PaleVioletRed4",
+            "maroon1",
+            "maroon2",
+            "maroon3",
+            "maroon4",
+            "VioletRed1",
+            "VioletRed2",
+            "VioletRed3",
+            "VioletRed4",
+            "magenta1",
+            "magenta2",
+            "magenta3",
+            "magenta4",
+            "orchid1",
+            "orchid2",
+            "orchid3",
+            "orchid4",
+            "plum1",
+            "plum2",
+            "plum3",
+            "plum4",
+            "MediumOrchid1",
+            "MediumOrchid2",
+            "MediumOrchid3",
+            "MediumOrchid4",
+            "DarkOrchid1",
+            "DarkOrchid2",
+            "DarkOrchid3",
+            "DarkOrchid4",
+            "purple1",
+            "purple2",
+            "purple3",
+            "purple4",
+            "MediumPurple1",
+            "MediumPurple2",
+            "MediumPurple3",
+            "MediumPurple4",
+            "thistle1",
+            "thistle2",
+            "thistle3",
+            "thistle4",
+            "gray0",
+            "grey0",
+            "gray1",
+            "grey1",
+            "gray2",
+            "grey2",
+            "gray3",
+            "grey3",
+            "gray4",
+            "grey4",
+            "gray5",
+            "grey5",
+            "gray6",
+            "grey6",
+            "gray7",
+            "grey7",
+            "gray8",
+            "grey8",
+            "gray9",
+            "grey9",
+            "gray10",
+            "grey10",
+            "gray11",
+            "grey11",
+            "gray12",
+            "grey12",
+            "gray13",
+            "grey13",
+            "gray14",
+            "grey14",
+            "gray15",
+            "grey15",
+            "gray16",
+            "grey16",
+            "gray17",
+            "grey17",
+            "gray18",
+            "grey18",
+            "gray19",
+            "grey19",
+            "gray20",
+            "grey20",
+            "gray21",
+            "grey21",
+            "gray22",
+            "grey22",
+            "gray23",
+            "grey23",
+            "gray24",
+            "grey24",
+            "gray25",
+            "grey25",
+            "gray26",
+            "grey26",
+            "gray27",
+            "grey27",
+            "gray28",
+            "grey28",
+            "gray29",
+            "grey29",
+            "gray30",
+            "grey30",
+            "gray31",
+            "grey31",
+            "gray32",
+            "grey32",
+            "gray33",
+            "grey33",
+            "gray34",
+            "grey34",
+            "gray35",
+            "grey35",
+            "gray36",
+            "grey36",
+            "gray37",
+            "grey37",
+            "gray38",
+            "grey38",
+            "gray39",
+            "grey39",
+            "gray40",
+            "grey40",
+            "gray41",
+            "grey41",
+            "gray42",
+            "grey42",
+            "gray43",
+            "grey43",
+            "gray44",
+            "grey44",
+            "gray45",
+            "grey45",
+            "gray46",
+            "grey46",
+            "gray47",
+            "grey47",
+            "gray48",
+            "grey48",
+            "gray49",
+            "grey49",
+            "gray50",
+            "grey50",
+            "gray51",
+            "grey51",
+            "gray52",
+            "grey52",
+            "gray53",
+            "grey53",
+            "gray54",
+            "grey54",
+            "gray55",
+            "grey55",
+            "gray56",
+            "grey56",
+            "gray57",
+            "grey57",
+            "gray58",
+            "grey58",
+            "gray59",
+            "grey59",
+            "gray60",
+            "grey60",
+            "gray61",
+            "grey61",
+            "gray62",
+            "grey62",
+            "gray63",
+            "grey63",
+            "gray64",
+            "grey64",
+            "gray65",
+            "grey65",
+            "gray66",
+            "grey66",
+            "gray67",
+            "grey67",
+            "gray68",
+            "grey68",
+            "gray69",
+            "grey69",
+            "gray70",
+            "grey70",
+            "gray71",
+            "grey71",
+            "gray72",
+            "grey72",
+            "gray73",
+            "grey73",
+            "gray74",
+            "grey74",
+            "gray75",
+            "grey75",
+            "gray76",
+            "grey76",
+            "gray77",
+            "grey77",
+            "gray78",
+            "grey78",
+            "gray79",
+            "grey79",
+            "gray80",
+            "grey80",
+            "gray81",
+            "grey81",
+            "gray82",
+            "grey82",
+            "gray83",
+            "grey83",
+            "gray84",
+            "grey84",
+            "gray85",
+            "grey85",
+            "gray86",
+            "grey86",
+            "gray87",
+            "grey87",
+            "gray88",
+            "grey88",
+            "gray89",
+            "grey89",
+            "gray90",
+            "grey90",
+            "gray91",
+            "grey91",
+            "gray92",
+            "grey92",
+            "gray93",
+            "grey93",
+            "gray94",
+            "grey94",
+            "gray95",
+            "grey95",
+            "gray96",
+            "grey96",
+            "gray97",
+            "grey97",
+            "gray98",
+            "grey98",
+            "gray99",
+            "grey99",
+            "gray100",
+            "grey100",
+            "dark grey",
+            "DarkGrey",
+            "dark gray",
+            "DarkGray",
+            "dark blue",
+            "DarkBlue",
+            "dark cyan",
+            "DarkCyan",
+            "dark magenta",
+            "DarkMagenta",
+            "dark red",
+            "DarkRed",
+            "light"
+    };
+    
+    // rgbents, rgbnames
+    public static boolean debugflag=false;
+    
+    static void debug(String msg)
+    {
+        if(debugflag)
+            System.out.println(msg);
+    }
+    
+    // look up string name of color. return int[3] of rgb, or
+    // null if color not found
+    public static int[] NameToRGB3(String str)
+    {
+        int rsize=rgbnames.length;
+        
+        for(int count=0;count<rsize; count++)
+        {
+            if(str.equalsIgnoreCase(rgbnames[count]))
+            {
+                return rgbents[count];
+            }
+        }
+        
+        return null;
+    }
+    
+    // This returns an int. If the int were represented as
+    // 0xffffffff, then the format would match data as
+    // 0x00rrggbb
+    //BUT.. returns 0xffffffff if color not found
+    public static int NameToRGB(String str)
+    {
+        int rsize=rgbnames.length;
+        
+        if(str.charAt(0)=='#'){
+            // Have to deal with rrggbb, OR rrrrggggbbbb
+            // Erm.. except this only deals with
+            // #rrggbb, it looks like... ?!!
+            String Substr=str.substring(1,7);
+            int rgb=Integer.parseInt(Substr,16);
+            rgb|=0xff000000;
+            return rgb;
+        }
+        
+        for(int count=0;count<rsize; count++)
+        {
+            if(str.equalsIgnoreCase(rgbnames[count]))
+            {
+                int ret;
+                ret =   0xff000000 |
+                (rgbents[count][0]<<16) |
+                (rgbents[count][1]<<8) |
+                rgbents[count][2];
+                
+                return ret;
+            }
+        }
+        if(!str.equalsIgnoreCase("None"))
+            debug("NameToRGB: Could not find match for color "+str);
+        return 0x00000000;
+    }
+    
+    public static String RGB3ToName(int val[])
+    {
+        if(val.length != 3)
+            return null;
+        
+        int rsize=rgbnames.length;
+        for(int count=0; count<rsize; count++)
+        {
+            if(val[0] ==rgbents[count][0])
+                if(val[1] ==rgbents[count][1])
+                    if(val[2] ==rgbents[count][2])
+                        return rgbnames[count];
+        }
+        
+        return null;
+    }
+    
+    
+    /************************************************************
+     * This part implements reading in xpm data, and doing something
+     * USEFUL with it. This is the only public routine that people
+     * will probably care about.
+     * xpm is possibly copyright/trademarked by Arnaud LE HORS,
+     * BULL Research, France. lehors@sophia.inria.fr
+     ************************************************************/
+    
+    // we dont care/try to deal with mono conversion
+    public static Image XpmToImage(String xpm) {
+        debug(xpm);
+        /* general rules I'm going to follow:
+         *
+         * skip all  (* xxxx*) but possibly insist on initial
+         *    (* XPM *)
+         * skip static char .....
+         * read "<width> <height> <colors> <charsperpixel>" <hotx,hoty>?
+         * Then in main reading;
+         * take c FIRST. fall back to s. fall back to g. fall back to g4.
+         *     fall back to m.
+         *
+         *
+         */
+        
+        if (xpm == null) {
+            debug("XpmToImage : Provided xpm is null!");
+            return null;
+        }
+        
+        int parse, parseend;
+        int width, height,colcount,charsperpixel;
+        Hashtable colorlookup = new Hashtable();
+        // add default val for "transparent"
+        // the initial 0xff should mean it should not show up
+        
+        
+        if(! xpm.startsWith("/* XPM */"))
+        {
+            debug("xpm data doesn't start with XPM magic. exit");
+            debug(xpm.substring(0,10));
+            return null;
+        }
+        
+        /*********************************************
+         * Do initial width/size,etc parsing
+         **********************************************/
+        parse          =       xpm.indexOf('"', 9);
+        parse+=1;
+        
+        parseend=xpm.indexOf(' ', parse);
+        width=Integer.parseInt(xpm.substring(parse,parseend));
+        
+        parse=parseend+1;
+        parseend=xpm.indexOf(' ', parse);
+        height=Integer.parseInt(xpm.substring(parse,parseend));
+        
+        parse=parseend+1;
+        parseend=xpm.indexOf(' ', parse);
+        colcount=Integer.parseInt(xpm.substring(parse,parseend));
+        
+        parse=parseend+1;
+        parseend=xpm.indexOf('"',parse);
+        if(parseend==-1){
+            return null;
+        }
+        charsperpixel=Integer.parseInt(xpm.substring(parse,parseend));
+        
+        debug("width="+width+",height="+height+
+                ",colcount="+colcount+",cpp="+charsperpixel);
+        
+        
+        
+        if(charsperpixel==1){
+            colorlookup.put(new Integer(' '),
+                    new Integer(0x00000000));
+        } else {
+            int tmpchar=(' ' &0xff) <<8;
+            tmpchar |=  (' '&0xff);
+            colorlookup.put(new Integer((tmpchar&0xffff)),
+                    new Integer(0x00000000));
+            
+        }
+        
+        /**************************************************
+         * Now do parsing of color naming/indexing
+         **************************************************/
+        Image image;
+        int imageb[];
+        
+        imageb = new int[width * height];
+        int bytecount=0; // counting bytes into image array
+        
+        parse=xpm.indexOf('"', parseend+1)+1;
+        
+        while(colcount-->0)
+        {
+            if(parse==0){
+                debug("ERROR: expecting color def");
+                return null;
+            }
+            
+            Integer colref;
+            Integer rgb;
+            parseend=xpm.indexOf('"', parse+1);
+            
+            String colorname =
+                getColorName(xpm.substring(parse, parseend));
+            
+            if(debugflag){
+                debug("colorname on line is "+colorname);
+                debug("now parsing "+
+                        xpm.substring(parse,parse+charsperpixel));
+                
+            }
+            
+            if(charsperpixel==1){
+                colref=new Integer(xpm.charAt(parse++));
+            } else{
+                int tmpchar=xpm.charAt(parse++);
+                tmpchar = (tmpchar&0xff)<<8;
+                tmpchar |= xpm.charAt(parse++) & 0xff;
+                
+                if(debugflag){
+                    debug("two charsperpixel: substre==" +
+                            xpm.substring(parse-2,parse)+
+                            " which generates char "+
+                            (tmpchar&0xffff));
+                }
+                
+                colref=new Integer(tmpchar&0xffff);
+            }
+            
+            
+            
+            rgb = new Integer(NameToRGB(colorname));
+            
+            if(debugflag){
+                debug("Color num parsed for \"" +colorname+"\"("+
+                        Integer.toHexString(colref.intValue())+
+                        ") is #"+
+                        Integer.toHexString(rgb.intValue()) );
+            }
+            
+            
+            colorlookup.put(colref, rgb);
+            parse=xpm.indexOf('"', parseend+1)+1;
+            
+            
+        }
+        
+        debug("Done with color defs");
+        
+        /****************************************************
+         * Finally, now that we have all the data,
+         * fully interpret the actual image
+         ***************************************************/
+        
+        parse = xpm.indexOf("\n\"", parseend+1);
+        if(parse==-1)
+        {
+            debug("ERROR; incomplete Xpm data");
+            return null;
+        }
+        parse+=1;
+        
+        debug("Xpm starting image parse");
+        while(xpm.charAt(parse) =='"')
+        {
+            parse++;
+            parseend = xpm.indexOf('"', parse);
+            
+            debug("Xpm; parsing \""+xpm.substring(parse, parseend)+"\"");
+            
+            for(int pix=parse; pix<parseend;pix++)
+            {
+                int tmpchar;
+                Integer pixchar;
+                Integer pixval;
+                
+                if(charsperpixel==1){
+                    tmpchar=xpm.charAt(pix);
+                } else{
+                    tmpchar=xpm.charAt(pix++);
+                    tmpchar = (tmpchar&0xff)<<8;
+                    tmpchar |= xpm.charAt(pix) & 0xff;
+                    
+                }
+                pixchar=new Integer(tmpchar&0xffff);
+                
+                
+                pixval = (Integer)colorlookup.get(pixchar);
+                if(pixval==null){
+                    if(debugflag){
+                        debug("HEY MORON: no value stored "+
+                                " for int "+
+                                Integer.toHexString(tmpchar)+
+                                ", char substring "+
+                                xpm.substring(pix-charsperpixel,
+                                        pix));
+                    }
+                    
+                }
+                imageb[bytecount++]=pixval.intValue();
+            }
+            
+            parse=xpm.indexOf('"', parseend+1);
+            if(parse==-1)
+                break;
+        }
+        
+        if(bytecount<(width * height -1))
+        {
+            debug("Warning.. pixmap truncated!");
+        }
+        
+        //printbytes(imageb);
+        image=BytesToImage(imageb, width, height);
+        
+        return image;
+        
+        
+    }
+    
+    static Image BytesToImage(int bytes[], int width, int height)
+    {
+        Image myimage;
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        myimage=tk.createImage(new MemoryImageSource(width, height, bytes, 0, width));
+        
+        return myimage;
+        
+    }
+    
+    // debug routine
+    static void printbytes(int b[])
+    {
+        int index;
+        for(index=0; index<b.length; index++)
+        {
+            System.out.print(" "+Integer.toHexString(b[index]));
+        }
+        System.out.println(" ");
+    }
+    
+    // This just parses out the string that defines the colorname
+    // we do NOT interpret. we just split it out from the rest of
+    // the line. Call NameToRGB() on the result.
+    // We make the assumption that our string does NOT
+    // have a trailing '"'
+    static String getColorName(String xpmline)
+    {
+        //debug("getColorName passed: "+xpmline);
+        
+        int parsemid, parsemidend;
+        parsemid = xpmline.indexOf("\tc");
+        if(parsemid <=0)
+            parsemid = xpmline.indexOf(" c");
+        if(parsemid <=0)
+        {
+            debug("Xpm: oops. no c found, in: "+xpmline);
+            return null;
+        }
+        parsemid+=3;
+        parsemidend=xpmline.indexOf('\t',parsemid);
+        if(parsemidend==-1)
+            parsemidend=xpmline.length();
+        
+        return xpmline.substring(parsemid, parsemidend);
+        
+        
+    }
+    
+    
+    
+}
diff --git a/src/org/biojava/dasobert/das2/Das2Capability.java b/src/org/biojava/dasobert/das2/Das2Capability.java
new file mode 100755 (executable)
index 0000000..7bb1e89
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Feb 9, 2006
+ *
+ */
+package org.biojava.dasobert.das2;
+
+public interface Das2Capability {
+
+    public boolean equals(Das2Capability other);
+    public int hashCode();
+    
+    public void setCapability(String type);
+    public String getCapability();
+    
+    public void setQueryUri(String id);
+    public String getQueryUri();
+    
+    public void setFormats(String[] formats);
+    public String[] getFormats();
+    
+    /** checks if this capability is actually of das1 style
+     * 
+     * @return
+     */
+    public boolean isDas1Style();
+    
+}
diff --git a/src/org/biojava/dasobert/das2/Das2CapabilityImpl.java b/src/org/biojava/dasobert/das2/Das2CapabilityImpl.java
new file mode 100755 (executable)
index 0000000..48f0a8a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Feb 9, 2006
+ *
+ */
+package org.biojava.dasobert.das2;
+
+public class Das2CapabilityImpl 
+implements Das2Capability{
+
+    String capability;
+    String[] formats;
+    String queryId;
+    
+    public static String DAS1_CAPABILITY_PREFIX = "das1";
+    
+    public Das2CapabilityImpl() {
+        super();
+        capability = "undef";
+        queryId = "";
+        formats = new String[0];
+
+    }
+    
+    public boolean isDas1Style(){
+        
+        if ( capability == null)
+            return false;
+        if ( capability.length() < DAS1_CAPABILITY_PREFIX.length())
+            return false;
+        if ( capability.substring(0,DAS1_CAPABILITY_PREFIX.length()).equals(DAS1_CAPABILITY_PREFIX))
+            return true;
+        return false;
+    
+    }
+    
+    public boolean equals(Das2Capability other){
+        
+        boolean status = true;
+        
+        if (!  capability.equals(other.getCapability()))
+            status = false;
+        if ( ! queryId.equals(other.getQueryUri()))
+            status = false;
+        
+        return status;
+    }
+    
+    public int hashCode(){
+        int h = 7;
+        h = 31 * h + ( null == capability ? 0 : capability.hashCode()) ;
+        h = 31 * h + ( null == queryId    ? 0 : queryId.hashCode()) ;
+        
+        return h;
+    }
+    
+    public String toString(){
+        String txt ="capability " + capability + " queryId " + queryId;
+        return txt;
+    }
+
+    public String getCapability() {
+        
+        return capability;
+    }
+
+    public String[] getFormats() {      
+        return formats;
+    }
+
+    public String getQueryUri() {      
+        return queryId;
+    }
+
+    public void setCapability(String type) {
+       capability = type;
+        
+    }
+
+    public void setFormats(String[] formats) {
+       
+        this.formats = formats; 
+    }
+
+    public void setQueryUri(String id) {
+       queryId = id;
+        
+    }
+    
+    
+
+}
diff --git a/src/org/biojava/dasobert/das2/Das2Source.java b/src/org/biojava/dasobert/das2/Das2Source.java
new file mode 100755 (executable)
index 0000000..437acb5
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Feb 9, 2006
+ *
+ */
+package org.biojava.dasobert.das2;
+
+import org.biojava.dasobert.dasregistry.DasSource;
+
+public interface Das2Source
+extends DasSource {
+
+   public Das2Capability[] getDas2Capabilities();
+   public void setDas2Capabilities(Das2Capability[] capabilities);
+   
+   /** test if this is a DAS1 source represented as a DAS2 source
+    *  if true - this source can be converted into a DAS1 source by using
+    *  DasSourceConverter.toDas1(Das2Source);
+    *
+    */
+   public boolean hasDas1Capabilities();
+}
diff --git a/src/org/biojava/dasobert/das2/Das2SourceImpl.java b/src/org/biojava/dasobert/das2/Das2SourceImpl.java
new file mode 100755 (executable)
index 0000000..aca49b2
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Feb 9, 2006
+ *
+ */
+package org.biojava.dasobert.das2;
+
+import org.biojava.dasobert.dasregistry.Das1Source;
+import org.biojava.dasobert.dasregistry.DasSource;
+
+public class Das2SourceImpl 
+extends Das1Source
+implements Das2Source 
+
+{
+
+    Das2Capability[] capabilities;
+    
+    public Das2SourceImpl() {
+        super();
+
+        capabilities = new Das2Capability[0];
+    }
+    
+    
+    /**  compare if two DasSources are identical
+     * 
+     */
+    public boolean equals(DasSource other){
+        
+        if ( this == other)
+            return true;
+        
+        if ( ( other == null) || (other.getClass() != this.getClass()))    
+            return false;
+       
+        // to compare if two Das2Sources are identical we do the following:
+        //  we check the capabilities
+        
+        Das2SourceImpl d2o = (Das2SourceImpl)other;
+        
+        if ( nickname.equals(d2o.getNickname()))
+            return true;
+        
+        Das2Capability[] othercaps = d2o.getDas2Capabilities();
+        
+        if ( ! (capabilities.length == othercaps.length))
+            return false;
+        
+        for ( int x=0;x<capabilities.length;x++){
+            Das2Capability tmpcap = capabilities[x];
+            boolean foundCap = false;
+            for (int y=0; y< othercaps.length;y++){
+                Das2Capability tmpcapo = othercaps[y];
+                if ( tmpcap.equals(tmpcapo))
+                    foundCap = true;
+            }
+            if ( ! foundCap)
+                return false;
+        }
+        
+        
+        //TODO?
+        // should we add a check for coordinate systems?
+        // but we already check for the endpoints, that should be enough...
+        
+        return true;
+        
+    }
+    
+    public int hashCode(){
+        int h = 7 ;
+        
+        h = 31 * h + (null == nickname ? 0 :  nickname.hashCode());
+        
+        for ( int x=0;x<capabilities.length;x++){
+            Das2Capability cap = capabilities[x];
+            h = 31 * h + cap.hashCode();
+        }
+        
+        return h;
+    }
+    
+    
+    public boolean hasDas1Capabilities(){
+        
+        // test if any of the capabilities is a das1 capabilitiy
+        
+        for (int i = 0 ; i < capabilities.length; i++) {
+            Das2Capability cap = capabilities[i];
+            if ( cap.isDas1Style())
+                return true;            
+        }
+        return false;
+        
+        
+    }
+    
+    public String[] getCapabilities() {
+        //todo mark as not needed / not appropriate ...
+        return super.getCapabilities();
+    }
+
+
+
+    public void setCapabilities(String[] u) {
+        // TODO Auto-generated method stub
+        super.setCapabilities(u);
+    }
+
+
+
+    public Das2Capability[] getDas2Capabilities() {
+        // TODO Auto-generated method stub
+        return capabilities;
+    }
+
+    public void setDas2Capabilities(Das2Capability[] capabilities) {
+        // TODO Auto-generated method stub
+        this.capabilities = capabilities;
+        
+    }
+    
+    
+    
+
+}
diff --git a/src/org/biojava/dasobert/das2/DasSourceConverter.java b/src/org/biojava/dasobert/das2/DasSourceConverter.java
new file mode 100755 (executable)
index 0000000..4fb294a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on Mar 23, 2006
+ *
+ */
+package org.biojava.dasobert.das2;
+
+import org.biojava.dasobert.dasregistry.Das1Source;
+
+public class DasSourceConverter {
+
+    public DasSourceConverter() {
+        super();
+
+    }
+
+
+    /** convert a das2 source to a das 1 source.
+     * This only will work if is passes the Das2Source.isDas1Source() test
+     * i.e. this is really a das1 server there
+     *
+     * @return
+     */
+    public static Das1Source toDas1Source (Das2Source das2source) throws Exception{
+        if ( ! das2source.hasDas1Capabilities())
+            throw new Exception("this das source does not have das1 capabilitites");
+
+        Das1Source ds = new Das1Source();
+        ds.setAdminemail(das2source.getAdminemail());
+        ds.setDescription(das2source.getDescription());
+        ds.setHelperurl(das2source.getHelperurl());
+        ds.setRegisterDate(das2source.getRegisterDate());
+        ds.setLeaseDate(das2source.getLeaseDate());
+        ds.setLabels(das2source.getLabels());
+        ds.setCoordinateSystem(das2source.getCoordinateSystem());
+        ds.setNickname(das2source.getNickname());
+        ds.setId(das2source.getId());
+
+        // convert the capabilitites to das1 capabiltities and get the url
+        Das2Capability[] caps = das2source.getDas2Capabilities();
+        String[] das1capabilitites = new String[caps.length];
+        int DASPREFIXLENGTH = 4;
+        for ( int i = 0 ; i< caps.length;i++){
+            Das2Capability cap = caps[i];
+
+            String c = cap.getCapability();
+            das1capabilitites[i] = c.substring(4,c.length());
+            String query_uri = cap.getQueryUri();
+
+            String url = query_uri.substring(0,(query_uri.length() - c.length() + DASPREFIXLENGTH));
+            ds.setUrl(url);
+        }
+        ds.setCapabilities(das1capabilitites);
+
+        return ds ;
+    }
+
+}
diff --git a/src/org/biojava/dasobert/dasregistry/Das1Source.java b/src/org/biojava/dasobert/dasregistry/Das1Source.java
new file mode 100755 (executable)
index 0000000..c962895
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 15.04.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.dasregistry;
+
+import java.util.Date ;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+
+
+/** a simple Bean class to be returned via SOAP
+ * @author Andreas Prlic
+ */
+
+public class Das1Source implements DasSource {
+    String url                ;
+    protected String nickname           ;
+    String adminemail         ;
+    String description        ;
+    DasCoordinateSystem[] coordinateSystem ;
+    String[] capabilities     ;
+    String[] labels           ;
+    String helperurl          ;
+    Date   registerDate       ;
+    Date   leaseDate          ;
+    String id                 ;
+    boolean local;
+
+    boolean alertAdmin;
+
+    public static String EMPTY_ID = "UNK:-1" ;
+
+    public Das1Source () {
+        id               = EMPTY_ID;
+        url              = "";
+        adminemail       = "" ;
+        description      = "" ;
+        //String empty     = "" ;
+        nickname         = "" ;
+        coordinateSystem = new DasCoordinateSystem[0];
+        //coordinateSystem[0] = new DasCoordinateSystem();
+        capabilities     =  new String[0];
+        labels                  = new String[0];
+        //capabilities[0]  = empty ;
+        registerDate     = new Date() ;
+        leaseDate        = new Date() ;
+        helperurl        = "";
+        local=true;
+    }
+
+
+    public boolean equals(DasSource other){
+        System.out.println("Das1Source equals, comparing with other DasSource");
+        if (! (other instanceof Das1Source))
+            return false;
+
+        Das1Source ods = (Das1Source) other;
+
+        if ( ods.getUrl().equals(url))
+            return true;
+        if ( ods.getNickname().equals(nickname))
+            return true;
+        return false;
+    }
+
+    public int hashCode() {
+        int h = 7;
+
+        h = 31 * h + ( null == nickname ? 0 : nickname.hashCode());
+        h = 31 * h + ( null == url ? 0 : url.hashCode());
+
+        return h;
+    }
+
+    public void setLocal(boolean flag){ local = flag;}
+    public boolean isLocal(){return local;}
+
+    public void setId(String i) { id = i; }
+
+    /** get a the Id of the DasSource. The Id is a unique db
+     * identifier. The public DAS-Registry has Auto_Ids that look like
+     * DASSOURCE:12345; public look like XYZ:12345, where the XYZ
+     * prefix can be configured in the config file.
+     */
+    public String getId() { return id;}
+
+    public void setNickname(String name) {
+        nickname = name ;
+    }
+    public String getNickname(){
+        return nickname;
+    }
+    public void setUrl(String u) {
+        char lastChar = u.charAt(u.length()-1);
+        if ( lastChar  != '/')
+            u += "/";
+
+        url = u ;
+    }
+
+    public void setAdminemail (String u) {
+        adminemail = u ;
+    }
+
+    public void setDescription (String u) {
+        description = u;
+    }
+
+    public void setCoordinateSystem (DasCoordinateSystem[] u){
+        coordinateSystem=u ;
+    }
+
+    public void setCapabilities (String[] u){
+        capabilities = u ;
+    }
+
+    public String getUrl(){return url;}
+    public String getAdminemail(){return adminemail;}
+    public String getDescription(){return description;}
+    public String[] getCapabilities(){return capabilities;}
+    public DasCoordinateSystem[] getCoordinateSystem(){return coordinateSystem;}
+
+    public void setRegisterDate(Date d) {
+        registerDate = d;
+    }
+    public Date getRegisterDate() {
+        return registerDate ;
+    }
+    public void setLeaseDate(Date d) {
+        leaseDate =d ;
+    }
+    public Date getLeaseDate() {
+        return leaseDate ;
+    }
+
+    public void setLabels(String[] ls) {
+        labels = ls ;
+    }
+
+    public String[] getLabels() {
+        return labels;
+    }
+
+    public void setHelperurl(String url) {
+        helperurl = url;
+    }
+
+    public String getHelperurl() {
+        return helperurl;
+    }
+
+    public void setAlertAdmin(boolean flag) {
+        alertAdmin = flag;
+    }
+
+    public boolean getAlertAdmin() {
+        return alertAdmin;
+    }
+
+}
diff --git a/src/org/biojava/dasobert/dasregistry/Das1Validator.java b/src/org/biojava/dasobert/dasregistry/Das1Validator.java
new file mode 100755 (executable)
index 0000000..e87ecd8
--- /dev/null
@@ -0,0 +1,514 @@
+/*                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 30.08.2005
+ * @author Andreas Prlic
+ *
+ */
+
+
+package org.biojava.dasobert.dasregistry ;
+
+//import org.biojava.services.das.*;
+//xml stuff
+import org.xml.sax.*;
+import javax.xml.parsers.*;
+import java.util.ArrayList                    ;
+import java.util.Map                          ;
+import java.util.List                         ;
+import java.io.InputStream                    ;
+
+import java.net.URL                           ;
+
+
+//for validation add dependency on SPICE... :-/
+import java.net.HttpURLConnection;
+import org.biojava.dasobert.das.*;
+import org.biojava.dasobert.das.DAS_Entry_Points_Handler;
+import org.biojava.dasobert.das.DAS_Types_Handler;
+
+
+
+public class Das1Validator {
+
+    public final static String[] DAS_CAPABILITIES = {
+        "sequence",
+        "structure",
+        "alignment",
+        "types",
+        "features",
+        "entry_points",
+        "dna",
+        "stylesheet"
+    } ;
+
+
+    //private final static String DATASOURCE_NAME = "jdbc/mysql";
+    String validationMessage;
+
+    public boolean VALIDATION = false; // DTD validation ..
+
+    List all_capabilities;
+    public Das1Validator() {
+        validationMessage = "" ;
+        all_capabilities = new ArrayList();
+        for ( int i = 0 ; i< DAS_CAPABILITIES.length; i++ ) {
+            all_capabilities.add(DAS_CAPABILITIES[i]);
+        }
+    }
+
+    /** return which errors have been produced during validation... */
+    public String getValidationMessage(){
+        return validationMessage;
+    }
+
+
+
+    public String[] validate(String url, DasCoordinateSystem[] coords, String[] capabilities){
+        validationMessage="";
+        // a list containing all valid DAS requests ...
+
+        List lst =new ArrayList();
+
+        char lastChar = url.charAt(url.length()-1);
+        if ( lastChar  != '/')
+            url += "/";
+
+        validateURL(url);
+
+
+        // test if all specified capabilities really work
+        for ( int c = 0 ; c < capabilities.length ; c++) {
+            String capability = capabilities[c];
+            if ( all_capabilities.contains(capability)) {
+                //System.out.println("testing " + capability);
+
+                if ( capability.equals("sequence")) {
+                    for ( int i=0;i< coords.length;i++){
+                        DasCoordinateSystem ds =coords[i];
+                        String testcode = ds.getTestCode();
+
+                        // do a DAS sequence retreive
+                        if (  validateSequence(url,testcode) )
+                            lst.add(capability);
+
+                    }
+
+                }
+                else if ( capability.equals("structure")) {
+
+                }
+                else if ( capability.equals("features")){
+                    for ( int i=0;i< coords.length;i++){
+                        DasCoordinateSystem ds =coords[i];
+                        String testcode = ds.getTestCode();
+
+
+                        if ( validateFeatures(url,testcode))
+                            lst.add(capability);
+
+                    }
+                }
+                else if ( capability.equals("alignment")){
+
+                } else if ( capability.equals("types")){
+                    if ( validateTypes(url))
+                        lst.add(capability);
+                    //else
+                    //    error =true ;
+
+                } else if ( capability.equals("entry_points")) {
+                    if ( validateEntry_Points(url))
+                        lst.add(capability);
+                    //else
+                    //    error = true;
+                } else if ( capability.equals("stylesheet")) {
+                    if ( validateStylesheet(url))
+                        lst.add(capability);
+                    //} else
+                    //    error = true;
+                } else if ( capability.equals("dna")){
+                    for ( int i=0;i< coords.length;i++){
+                        DasCoordinateSystem ds =coords[i];
+                        String testcode = ds.getTestCode();
+
+                        if ( validateDNA(url,testcode))
+                            lst.add(capability);
+                    }
+                }
+                else {
+                    validationMessage += "<br/>---<br/> test of capability " + capability + " not implemented,yet.";
+                    lst.add(capability);
+                }
+            }
+        }
+
+        //if ( error) {
+        //    System.out.println("DasValidator: "+ validationMessage);
+        //}
+        //this.validationMessage = validationMessage;
+        return (String[])lst.toArray(new String[lst.size()]);
+
+    }
+
+    /** make sure the URL matches the DAS spec
+     returns true if URL looks o.k...
+     */
+    public  boolean validateURL(String url) {
+        String[] spl = url.split("/");
+
+        //for (int i = 0 ; i < spl.length  ; i++ ) {
+        //    System.out.println("spl["+i+"]:"+spl[i]);
+        //}
+
+        if (spl == null ) {
+            validationMessage +="---<br/> URL is not well formed" ;
+            return false;
+        }
+
+        if ( spl.length <= 4) {
+            validationMessage +="---<br/> URL is not well formed <br/>" +
+            "should be http[s]://site.specific.prefix/das/dassourcename/";
+            return false;
+        }
+
+        //System.out.println("split 0 : " + spl[0]);
+        if ( ! (spl[0].equals("http:"))) {
+            if ( ! ( spl[0].equals("https:"))){
+                validationMessage +="---<br/> URL is not well formed (does not start with http:// or https://)" ;
+                return false;
+            }
+
+        }
+
+        String dastxt = spl[spl.length-2] ;
+        //System.out.println("should be >das< " + dastxt);
+        if ( ! dastxt.equals("das")) {
+            String suggestion = spl[0] + "//" ;
+            String wrong      = spl[0] + "//" ;
+            for (int i = 2 ; i < spl.length -2 ; i++ ) {
+                suggestion += spl[i] + "/" ;
+                wrong += spl[i] + "/" ;
+            }
+            suggestion +="<b>das</b>/"+spl[spl.length-1];
+            wrong +="<b>" + spl[spl.length-2] + "</b>/"+spl[spl.length-1];
+            validationMessage +="--<br/> the URL does not match the DAS spec. it should be <br/>"+
+            " http[s]://site.specific.prefix/das/dassourcename/ <br/>" +
+            " found >" + dastxt +" < instead of >das< <br/>" +
+            " suggested url: " + suggestion + "<br/>"+
+            " instead of: " + wrong ;
+            return false;
+        }
+        return true;
+
+    }
+
+    private boolean validateDNA(String url, String testcode){
+        try {
+            String cmd = url+"dna?segment="+testcode;
+            URL strurl = new URL(cmd);
+            InputStream dasInStream = open(strurl);
+
+            XMLReader xmlreader = getXMLReader();
+
+            DAS_DNA_Handler cont_handle = new DAS_DNA_Handler() ;
+
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+
+            insource.setByteStream(dasInStream);
+            xmlreader.parse(insource);
+            String sequence = cont_handle.get_sequence();
+            if ( sequence.length() > 0 ) {
+                return true;
+            } else {
+                validationMessage  +="<br/>---<br/> contacting " + cmd + "<br/>";
+                validationMessage += " no sequence was returned";
+
+                return false;
+            }
+
+
+        } catch ( Exception e) {
+            //e.printStackTrace();
+            validationMessage += "<br/>---<br/> contacting " + url + "dna?segment="+testcode + "<br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+        }
+        return false;
+
+    }
+
+    private boolean validateStylesheet(String url) {
+        try {
+            DAS_StylesheetRetrieve dsr = new DAS_StylesheetRetrieve();
+            URL styleurl = new URL(url+"stylesheet");
+
+            Map[] stylesheet = dsr.retrieve(styleurl);
+            if (( stylesheet != null ) && ( stylesheet.length > 0))
+                return true;
+            else {
+                validationMessage  +="<br/>---<br/> contacting " + url + "stylesheet<br/>";
+                validationMessage += " no stylesheet was returned";
+                return false;
+            }
+        } catch (Exception e) {
+            validationMessage += "<br/>---<br/> contacting " + url+"stylesheet <br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+        }
+        return false;
+    }
+
+
+    private boolean validateEntry_Points(String url){
+        try {
+            URL u = new URL(url+"entry_points");
+
+            InputStream dasInStream = open(u);
+
+            XMLReader xmlreader = getXMLReader();
+
+            DAS_Entry_Points_Handler cont_handle = new DAS_Entry_Points_Handler() ;
+
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+            insource.setByteStream(dasInStream);
+            xmlreader.parse(insource);
+            String version = cont_handle.getVersion();
+            if ( version != null ) {
+                return true;
+            } else {
+                validationMessage  +="<br/>---<br/> contacting " + url +"entry_points <br/>";
+                validationMessage += " no version was returned";
+
+                return false;
+            }
+
+
+        } catch ( Exception e) {
+            //e.printStackTrace();
+            validationMessage += "<br/>---<br/> contacting " + url+ "types <br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+        }
+        return false;
+    }
+
+    private boolean validateTypes(String url){
+        try {
+            URL u = new URL(url+"types");
+            InputStream dasInStream = open(u);
+            XMLReader xmlreader = getXMLReader();
+
+            DAS_Types_Handler cont_handle = new DAS_Types_Handler() ;
+
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+            insource.setByteStream(dasInStream);
+            xmlreader.parse(insource);
+            String[] types = cont_handle.getTypes();
+            if ( types.length > 0 ) {
+                return true;
+            } else {
+                validationMessage  +="<br/>---<br/> contacting " + url +"types <br/>";
+                validationMessage += " no types were returned";
+
+                return false;
+            }
+
+
+        } catch ( Exception e) {
+            //e.printStackTrace();
+            validationMessage += "<br/>---<br/> contacting " + url+ "types <br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+        }
+        return false;
+    }
+
+
+    private boolean validateFeatures(String url, String testcode){
+        try {
+            URL u = new URL(url+"features?segment="+testcode);
+            InputStream dasInStream = open(u);
+            XMLReader xmlreader = getXMLReader();
+
+            DAS_Feature_Handler cont_handle = new DAS_Feature_Handler() ;
+            cont_handle.setDASCommand(url.toString());
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+            insource.setByteStream(dasInStream);
+            xmlreader.parse(insource);
+            List features = cont_handle.get_features();
+            if ( features.size() > 0 ) {
+                return true;
+            } else {
+                validationMessage  +="<br/>---<br/> contacting " + url+"features?segment="+testcode + "<br/>";
+                validationMessage += " no features were returned";
+
+                return false;
+            }
+
+        } catch ( Exception e) {
+            //e.printStackTrace();
+            validationMessage += "<br/>---<br/> contacting " + url+"features?segment="+testcode + "<br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+        }
+        return false;
+    }
+     private boolean validateSequence(String url, String testcode) {
+        URL dasUrl;
+        String cmd = url+"sequence?segment="+testcode;
+        try {
+            dasUrl = new URL(cmd);
+
+        } catch ( Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+        try {
+            InputStream dasInStream =open(dasUrl);
+            SAXParserFactory spfactory =
+                SAXParserFactory.newInstance();
+            spfactory.setValidating(true);
+
+            SAXParser saxParser = null ;
+
+            try{
+                saxParser =
+                    spfactory.newSAXParser();
+            } catch (ParserConfigurationException e) {
+                e.printStackTrace();
+            }
+            XMLReader xmlreader = saxParser.getXMLReader();
+
+            try {
+                xmlreader.setFeature("http://xml.org/sax/features/validation", VALIDATION);
+            } catch (SAXException e) {
+                e.printStackTrace();
+            }
+            try {
+                xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",VALIDATION);
+            } catch (SAXNotRecognizedException e){
+                e.printStackTrace();
+            }
+
+            DAS_Sequence_Handler cont_handle = new DAS_Sequence_Handler() ;
+            xmlreader.setContentHandler(cont_handle);
+            xmlreader.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
+            InputSource insource = new InputSource() ;
+            insource.setByteStream(dasInStream);
+            xmlreader.parse(insource);
+            String sequence = cont_handle.get_sequence();
+            if ( ( sequence==null) || (sequence.equals(""))) {
+                validationMessage += "---<br/>contacting " + cmd +"<br/>";
+                validationMessage += "no sequence found";
+                return false;
+            }
+            return true;
+        } catch (Exception e) {
+            validationMessage += "---<br/>contacting " + cmd +"<br/>";
+
+            Throwable cause = e.getCause();
+            if ( cause != null)
+                validationMessage += cause.toString();
+            else
+                validationMessage += e.toString();
+            //e.printStackTrace();
+        }
+        return false;
+    }
+
+    private XMLReader getXMLReader() throws SAXException{
+        SAXParserFactory spfactory =
+            SAXParserFactory.newInstance();
+
+        spfactory.setValidating(false) ;
+        SAXParser saxParser = null ;
+
+        try{
+            saxParser =
+                spfactory.newSAXParser();
+        } catch (ParserConfigurationException e) {
+            e.printStackTrace();
+        }
+
+        XMLReader xmlreader = saxParser.getXMLReader();
+        boolean validation = VALIDATION;
+        //XMLReader xmlreader = XMLReaderFactory.createXMLReader();
+        try {
+            xmlreader.setFeature("http://xml.org/sax/features/validation", validation);
+        } catch (SAXException e) {
+            e.printStackTrace();
+        }
+
+        try {
+            xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",validation);
+        } catch (SAXNotRecognizedException e){
+            e.printStackTrace();
+        }
+        return xmlreader;
+
+    }
+
+
+
+    private InputStream open(URL url) throws Exception{
+
+        // TODO Auto-generated method stub
+
+        InputStream inStream = null;
+
+        HttpURLConnection huc = null;
+        huc = (HttpURLConnection) url.openConnection();
+        //String contentEncoding = huc.getContentEncoding();
+        inStream = huc.getInputStream();
+        return inStream;
+    }
+
+
+
+
+
+}
diff --git a/src/org/biojava/dasobert/dasregistry/Das2Validator.java b/src/org/biojava/dasobert/dasregistry/Das2Validator.java
new file mode 100755 (executable)
index 0000000..a7fd293
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Mar 20, 2006
+ *
+ */
+package org.biojava.dasobert.dasregistry;
+
+import org.biojava.dasobert.das2.Das2Source;
+
+public class Das2Validator {
+
+    public Das2Validator() {
+        super();
+
+    }
+    
+    public boolean validate(Das2Source ds){
+        
+        // TODO this bit still needs to be implemented!
+        
+        return true;
+    }
+
+    
+    
+}
diff --git a/src/org/biojava/dasobert/dasregistry/DasCoordSysComparator.java b/src/org/biojava/dasobert/dasregistry/DasCoordSysComparator.java
new file mode 100755 (executable)
index 0000000..8715446
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 15.04.2004
+ * @author Andreas Prlic
+ *
+ */
+
+
+package org.biojava.dasobert.dasregistry ;
+
+import java.util.Comparator ;
+import java.util.Map ;
+import java.util.HashMap ;
+
+import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
+
+/** a comparator to sort DasSources 
+ * @author Andreas Prlic 
+ */
+
+
+public abstract class DasCoordSysComparator
+    implements Comparator
+{ 
+
+    private final String name ;
+    private static final Map COMPS_BY_NAME;
+
+
+    public DasCoordSysComparator(String str) {
+       //System.out.println("new dasSourceComparator " + str);
+       name = str ;
+    }
+   
+    public static final Comparator BY_NAME = new DasCoordSysComparator("name") {
+        protected Comparable getField(DasCoordinateSystem ds) {
+            return ds.getName();
+        }
+    };    
+
+    public static final Comparator BY_ID = new DasCoordSysComparator("id") {
+        protected Comparable getField(DasCoordinateSystem ds) {
+            return ds.getUniqueId();
+        }
+    };    
+    public static final Comparator BY_CATEGORY = new DasCoordSysComparator("category") {
+        protected Comparable getField(DasCoordinateSystem ds) {
+            return ds.getCategory();
+        }
+    };
+    public static final Comparator BY_ORGANISM = new DasCoordSysComparator("organism") {
+        protected Comparable getField(DasCoordinateSystem ds) {
+            return ds.getOrganismName();
+        }
+    };
+    public static final Comparator BY_TAXID = new DasCoordSysComparator("taxid") {
+        protected Comparable getField(DasCoordinateSystem ds) {
+            return ds.getNCBITaxId()+"";
+        }
+    };
+   
+    
+
+    static {
+        COMPS_BY_NAME = new HashMap();
+        COMPS_BY_NAME.put(BY_ID.toString(),           BY_ID);
+       COMPS_BY_NAME.put(BY_NAME.toString(),         BY_NAME);
+        COMPS_BY_NAME.put(BY_CATEGORY.toString(),     BY_CATEGORY);
+        COMPS_BY_NAME.put(BY_ORGANISM.toString(),     BY_ORGANISM);
+        COMPS_BY_NAME.put(BY_TAXID.toString(),        BY_TAXID);
+    }
+
+   
+
+    public static Comparator fromString(String name) {
+        if (COMPS_BY_NAME.containsKey(name)) {
+            return (Comparator) COMPS_BY_NAME.get(name);
+        } else {
+            throw new IllegalArgumentException("Can't compare by key " + name);
+        }
+    }
+
+    protected abstract Comparable getField(DasCoordinateSystem ds);
+
+    /** compare two DasCoordSys objects */
+    public int compare( Object a, Object b) {
+        DasCoordinateSystem x = (DasCoordinateSystem) a ;
+        DasCoordinateSystem y = (DasCoordinateSystem) b ;
+        return getField(x).compareTo(getField(y));
+    }
+
+    public String toString() {
+        return name;
+    }
+
+
+}
+
+
diff --git a/src/org/biojava/dasobert/dasregistry/DasCoordinateSystem.java b/src/org/biojava/dasobert/dasregistry/DasCoordinateSystem.java
new file mode 100755 (executable)
index 0000000..31caaf5
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 15.04.2004
+ * @author Andreas Prlic
+ *
+ */
+package org.biojava.dasobert.dasregistry;
+
+
+/** a Bean to be returned via SOAP. It takes care of the DAS -  coordinate Systems 
+ * @author Andreas Prlic
+ */
+public class DasCoordinateSystem {
+
+    String name;
+    String category;
+    String organism_name;
+    int ncbi_tax_id ;
+    String uniqueId ;
+    String version;
+    String testCode;
+    
+    public DasCoordinateSystem () {
+        uniqueId = "";
+        name = "";
+        category ="";
+        organism_name = "";
+        ncbi_tax_id = 0;
+        version = "";
+        testCode = "";
+    }
+
+    public boolean equals(DasCoordinateSystem other){
+        boolean match = true;
+        System.out.println("comparing " + this.toString() + " to " + other.toString());
+        // URI has piority 
+        if ( (! uniqueId.equals("")) && ( uniqueId.equals( other.getUniqueId())))
+            return true;
+        
+        if ( ncbi_tax_id != other.getNCBITaxId()) {
+            System.out.println("mismatch in ncbi tax id " + ncbi_tax_id + " != " + other.getNCBITaxId());
+            match = false;
+        }
+        if ( ! version.equals(other.getVersion() )){
+            System.out.println("mismatch in version");
+            match = false;
+        }
+        if ( ! category.equals(other.getCategory())  ) {
+            System.out.println("mismatch in category");
+            match = false;
+        }
+        if ( ! name.equals(other.getName())) {
+            System.out.println("mismatch in name");   
+            match = false;
+        }
+        System.out.println(" match: " + match);
+        
+        return match;
+    }
+    
+    public Object clone() {
+        DasCoordinateSystem d = new DasCoordinateSystem();
+        d.setTestCode(testCode);
+        d.setCategory(category);
+        d.setName(name);
+        d.setNCBITaxId(ncbi_tax_id);
+        d.setUniqueId(getUniqueId());
+        d.setOrganismName(getOrganismName());
+        d.setVersion(getVersion());
+        return d;
+    }
+    
+    public String getTestCode() {
+        return testCode;
+    }
+
+
+
+    public void setTestCode(String testCode) {
+        if ( testCode == null)
+            testCode = "";
+        this.testCode = testCode;
+    }
+
+
+
+    public void setUniqueId(String id) { uniqueId = id ;   }
+    public String getUniqueId() { return uniqueId;         }
+
+    public void setName(String n) { name = n; }
+    public String getName() { return name; }
+    
+    public void setCategory(String c) { category = c;}
+    public String getCategory() { return category;}
+
+    public void setOrganismName(String t) { organism_name  =t;} 
+    public String getOrganismName() { return organism_name;}
+
+    public void setNCBITaxId(int id) { ncbi_tax_id = id;}
+    public int getNCBITaxId(){ return ncbi_tax_id ;}
+    
+    
+    
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        if ( version == null)
+            version = "";
+        this.version = version;
+    }
+
+    public String toString() {
+        String nam = name;
+        if ( ! version.equals(""))
+            nam += "_" + version;
+        
+       if ( organism_name.equals("") ) 
+           return nam+","+category ;
+       else 
+           return nam+","+category+"," + organism_name ;
+    }
+
+    public static DasCoordinateSystem fromString(String rawString) {
+       String[] spl = rawString.split(",");
+       DasCoordinateSystem dcs = new DasCoordinateSystem();
+       if ( spl.length == 2 ) {
+           dcs.setName(spl[0]);           
+           dcs.setCategory(spl[1]);
+       } 
+       if ( spl.length == 3 ) {
+           dcs.setName(spl[0]);
+           dcs.setCategory(spl[1]);
+           dcs.setOrganismName(spl[2]);
+       }
+       return dcs;
+    }
+
+
+}
diff --git a/src/org/biojava/dasobert/dasregistry/DasSource.java b/src/org/biojava/dasobert/dasregistry/DasSource.java
new file mode 100755 (executable)
index 0000000..c9aee5d
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Feb 8, 2006
+ *
+ */
+package org.biojava.dasobert.dasregistry;
+
+import java.util.Date;
+
+public interface DasSource {
+
+    public  void setLocal(boolean flag);
+
+    public  boolean isLocal();
+
+    /** compare if two das sources are equal
+     * 
+     * @param ds
+     * @return
+     */
+    public boolean equals(DasSource ds);
+    
+    /** classes that implement equals, should also implement hashKey
+     * 
+     * @return
+     */
+    public int hashCode();
+    
+    
+    public  void setId(String i);
+
+    /** get a the Id of the DasSource. The Id is a unique db
+     * identifier. The public DAS-Registry has Auto_Ids that look like
+     * DASSOURCE:12345; public look like XYZ:12345, where the XYZ
+     * prefix can be configured in the config file.
+     */
+    public  String getId();
+
+    public  void setNickname(String name);
+
+    public  String getNickname();
+
+    public  void setUrl(String u);
+
+    public  void setAdminemail(String u);
+
+    public  void setDescription(String u);
+
+    public  void setCoordinateSystem(DasCoordinateSystem[] u);
+
+    public  void setCapabilities(String[] u);
+
+    public  String getUrl();
+
+    public  String getAdminemail();
+
+    public  String getDescription();
+
+    public  String[] getCapabilities();
+
+    public  DasCoordinateSystem[] getCoordinateSystem();
+
+    public  void setRegisterDate(Date d);
+
+    public  Date getRegisterDate();
+
+    public  void setLeaseDate(Date d);
+
+    public  Date getLeaseDate();
+
+    public  void setLabels(String[] ls);
+
+    public  String[] getLabels();
+
+    public  void setHelperurl(String url);
+
+    public  String getHelperurl();
+
+    // TestCode is now part of the coordinate system!
+    //public  void setTestCode(String code);
+    //public  String getTestCode();
+
+    public  void setAlertAdmin(boolean flag);
+
+    public  boolean getAlertAdmin();
+
+}
\ No newline at end of file
diff --git a/src/org/biojava/dasobert/dasregistry/DasSourceComparator.java b/src/org/biojava/dasobert/dasregistry/DasSourceComparator.java
new file mode 100755 (executable)
index 0000000..c07b32d
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ *                    BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on 15.04.2004
+ * @author Andreas Prlic
+ *
+ */
+
+
+package org.biojava.dasobert.dasregistry ;
+
+import java.util.Comparator ;
+import java.util.Map ;
+import java.util.HashMap ;
+
+
+/** a comparator to sort DasSources 
+ * @author Andreas Prlic, Thomas Down
+ */
+
+
+public abstract class DasSourceComparator
+    implements Comparator
+{ 
+
+    private final String name ;
+    private static final Map COMPS_BY_NAME;
+
+
+    public DasSourceComparator(String str) {
+       //System.out.println("new dasSourceComparator " + str);
+       name = str ;
+    }
+   
+    public static final Comparator BY_ID = new DasSourceComparator("id") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getId();
+        }
+    };    
+
+    public static final Comparator BY_NICKNAME = new DasSourceComparator("nickname") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getNickname();
+        }
+    };    
+    public static final Comparator BY_REGISTER_DATE = new DasSourceComparator("registerdate") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getRegisterDate();
+        }
+    };
+    public static final Comparator BY_LEASE_DATE = new DasSourceComparator("leasedate") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getLeaseDate();
+        }
+    };
+    public static final Comparator BY_URL = new DasSourceComparator("url") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getUrl();
+        }
+    };
+    public static final Comparator BY_ADMIN_EMAIL = new DasSourceComparator("adminemail") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getAdminemail();
+        }
+    };
+    public static final Comparator BY_DESCRIPTION = new DasSourceComparator("description") {
+        protected Comparable getField(DasSource ds) {
+            return ds.getDescription();
+        }
+    };
+    public static final Comparator BY_CAPABILITIES = new DasSourceComparator("capabilities") {
+        protected Comparable getField(DasSource ds) {
+            String[] caps = ds.getCapabilities();
+            return caps.length == 0 ? "" : caps[0];
+        }
+    };
+    public static final Comparator BY_COORDINATE_SYSTEM = new DasSourceComparator("coordinateSystem") {
+        protected Comparable getField(DasSource ds) {
+            DasCoordinateSystem[] dcss = ds.getCoordinateSystem();
+            return dcss.length == 0 ? "" : dcss[0].toString();
+        }
+    };
+
+    static {
+        COMPS_BY_NAME = new HashMap();
+        COMPS_BY_NAME.put(BY_ID.toString(),                BY_ID);
+        COMPS_BY_NAME.put(BY_NICKNAME.toString(),          BY_NICKNAME);
+        COMPS_BY_NAME.put(BY_REGISTER_DATE.toString(),     BY_REGISTER_DATE);
+        COMPS_BY_NAME.put(BY_LEASE_DATE.toString(),        BY_LEASE_DATE);
+        COMPS_BY_NAME.put(BY_URL.toString(),               BY_URL);
+        COMPS_BY_NAME.put(BY_ADMIN_EMAIL.toString(),       BY_ADMIN_EMAIL);
+        COMPS_BY_NAME.put(BY_DESCRIPTION.toString(),       BY_DESCRIPTION);
+        COMPS_BY_NAME.put(BY_CAPABILITIES.toString(),      BY_CAPABILITIES);
+        COMPS_BY_NAME.put(BY_COORDINATE_SYSTEM.toString(), BY_COORDINATE_SYSTEM);
+    }
+
+   
+
+    public static Comparator fromString(String name) {
+        if (COMPS_BY_NAME.containsKey(name)) {
+            return (Comparator) COMPS_BY_NAME.get(name);
+        } else {
+            throw new IllegalArgumentException("Can't compare by key " + name);
+        }
+    }
+
+    protected abstract Comparable getField(DasSource ds);
+
+    /** compare two DasSource objects */
+    public int compare( Object a, Object b) {
+        
+        DasSource x = (DasSource) a ;
+        DasSource y = (DasSource) b ;
+        return getField(x).compareTo(getField(y));
+    }
+
+    public String toString() {
+        return name;
+    }
+
+
+}
+
+
diff --git a/src/org/biojava/dasobert/dasregistry/DasSourceValidator.java b/src/org/biojava/dasobert/dasregistry/DasSourceValidator.java
new file mode 100755 (executable)
index 0000000..3e857b5
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ *
+ * Created on Mar 20, 2006
+ *
+ */
+package org.biojava.dasobert.dasregistry;
+
+import org.biojava.dasobert.das2.Das2Source;
+
+public class DasSourceValidator {
+
+    public DasSourceValidator() {
+        super();
+
+    }
+
+    public void validateDasSource(DasSource ds) throws Exception {
+
+        if ( ds instanceof Das2Source ){
+
+            Das2Source d2s = (Das2Source)ds;
+
+            Das2Validator validator = new Das2Validator();
+            boolean ok = validator.validate(d2s);
+            if ( ! ok)
+                throw new Exception("coul not validate DasSource");
+
+        } else {
+
+            // a DAS 1 source ...
+
+            String url =ds.getUrl();
+            String[] caps = ds.getCapabilities();
+            //String testCode = ds.getTestCode();
+
+            Das1Validator validator = new Das1Validator();
+
+            String[] okcaps = validator.validate(url,ds.getCoordinateSystem(),caps);
+            String validationMessage = validator.getValidationMessage();
+            if ( okcaps.length != caps.length){
+                throw new Exception("could not validate DasSource " + validationMessage);
+            }
+
+
+        }
+
+    }
+
+}
diff --git a/src/org/biojava/dasobert/eventmodel/AlignmentListener.java b/src/org/biojava/dasobert/eventmodel/AlignmentListener.java
new file mode 100755 (executable)
index 0000000..ba80ba1
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Nov 20, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+public interface AlignmentListener {
+
+    public void newAlignment(AlignmentEvent e);
+    public void noAlignmentFound(AlignmentEvent e);
+    public void clearAlignment();
+}
diff --git a/src/org/biojava/dasobert/eventmodel/FeatureEvent.java b/src/org/biojava/dasobert/eventmodel/FeatureEvent.java
new file mode 100755 (executable)
index 0000000..e941d89
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Oct 28, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+import java.util.Map;
+
+import org.biojava.dasobert.dasregistry.Das1Source;
+public class FeatureEvent {
+    
+    Map[] features;
+    Das1Source dasSource;
+    int comeBackLater;
+    
+    public FeatureEvent(Map[] features,Das1Source dasSource) {
+        super();
+        this.features =features;
+        this.dasSource = dasSource;
+        comeBackLater = -1;
+    }
+    
+    public int getComeBackLater(){
+        return comeBackLater;
+    }
+    
+    public void setComeBackLater(int comeBackLater){
+        this.comeBackLater = comeBackLater;
+    }
+    
+    
+    /** get the features that have been found.
+     * 
+     * do something like
+     * Map[] features = event.getFeatures();
+     * <pre>
+     * for (int i = 0 ; i< features;i++) {            
+     *      Map f = features[i];
+     *      String type = (String) f.get("TYPE") ;
+     *      System.out.println(type);
+     * }      
+     * </pre>
+     * @return
+     */
+    public Map[] getFeatures(){
+        return features;
+    }
+    
+    public Das1Source getDasSource(){
+        return dasSource;
+    }
+    
+}
+
diff --git a/src/org/biojava/dasobert/eventmodel/FeatureListener.java b/src/org/biojava/dasobert/eventmodel/FeatureListener.java
new file mode 100755 (executable)
index 0000000..0091ef1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Oct 28, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+//import org.biojava.spice.multipanel.eventmodel.FeatureEvent;
+
+/**  a feature listener that returns the raw features as returned by a DAS source.
+ * 
+ */  
+public interface FeatureListener {
+    
+    /** new features have been returned from the Annotation server 
+     * 
+     * @param e
+     */
+    public void newFeatures(FeatureEvent e);
+    
+    /** the server says that he is busy and we should try again in x seconds
+     * 
+     * @param e
+     */
+    public void comeBackLater(FeatureEvent e);
+    
+}
+
+    
+    
+    
+
diff --git a/src/org/biojava/dasobert/eventmodel/ObjectListener.java b/src/org/biojava/dasobert/eventmodel/ObjectListener.java
new file mode 100755 (executable)
index 0000000..7b136a4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Nov 1, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+/** an interface for the listeners of new PDB code requested / new Uniprot code requested
+ * 
+ * @author Andreas Prlic
+ *
+ */
+public interface ObjectListener {
+    
+    /** a new object has been requested 
+     * 
+     * @param accessionCode
+     */
+    public void newObjectRequested(String accessionCode);
+    
+    /** no object with that accessionCode has been found
+     * 
+     * @param accessionCode
+     */
+    public void noObjectFound(String accessionCode);
+    
+    
+   // public void exceptionOccured(Exception e);
+   
+}
diff --git a/src/org/biojava/dasobert/eventmodel/SequenceEvent.java b/src/org/biojava/dasobert/eventmodel/SequenceEvent.java
new file mode 100755 (executable)
index 0000000..c3123ff
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Nov 20, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+
+public class SequenceEvent {
+
+    String sequence;
+    String accessionCode;
+    public SequenceEvent(String accessionCode, String seq) {
+        super();
+        sequence = seq;
+        this.accessionCode = accessionCode;
+    }
+    
+    public String getAccessionCode(){
+        return accessionCode;
+    }
+    
+    public String getSequence(){
+        return sequence;
+    }
+
+}
diff --git a/src/org/biojava/dasobert/eventmodel/SequenceListener.java b/src/org/biojava/dasobert/eventmodel/SequenceListener.java
new file mode 100755 (executable)
index 0000000..9232dc9
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Jun 10, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+/** An interface fore events related to selections of sequence
+ * position, sequence range and locking of the selection.
+ *
+ * @author Andreas Prlic
+ *
+ */
+public interface SequenceListener 
+extends ObjectListener{
+    
+    /* select a certain sequence position */
+    public void selectedSeqPosition(int position);
+    
+    /** select a certain range of a sequence */
+    public void selectedSeqRange(int start, int end);
+    
+    /** the current selecetion is locked and can not be changed */
+    public void selectionLocked(boolean flag);
+    
+    public void newSequence(SequenceEvent e);
+    
+    /** clear what has been selected
+     * 
+     *
+     */
+    public void clearSelection();
+}
diff --git a/src/org/biojava/dasobert/eventmodel/StructureListener.java b/src/org/biojava/dasobert/eventmodel/StructureListener.java
new file mode 100755 (executable)
index 0000000..44fccac
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *                  BioJava development code
+ *
+ * This code may be freely distributed and modified under the
+ * terms of the GNU Lesser General Public Licence.  This should
+ * be distributed with the code.  If you do not have a copy,
+ * see:
+ *
+ *      http://www.gnu.org/copyleft/lesser.html
+ *
+ * Copyright for this code is held jointly by the individual
+ * authors.  These should be listed in @author doc comments.
+ *
+ * For more information on the BioJava project and its aims,
+ * or to join the biojava-l mailing list, visit the home page
+ * at:
+ *
+ *      http://www.biojava.org/
+ * 
+ * Created on Oct 31, 2005
+ *
+ */
+package org.biojava.dasobert.eventmodel;
+
+/** things that can happen to a structure
+ * 
+ * @author Andreas Prlic
+ *
+ */
+public interface StructureListener
+extends ObjectListener {
+
+  
+    /** this is thrown if a new structure has been obtained from a structre source
+     * 
+     * @param event
+     */
+    public void newStructure(StructureEvent event);
+    
+    /** this is thrown if the currently active chain is being changed
+     * 
+     * @param event
+     */
+    public void selectedChain(StructureEvent event);
+    
+    
+    
+}