From kawas at dev.open-bio.org Tue Dec 2 13:53:11 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:53:11 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021853.mB2IrBM9006660@dev.open-bio.org> kawas Tue Dec 2 13:53:11 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6624/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: added XML::SemanticCompare to the makefile (used by MobyUnitTest.pm) moby-live/Perl/MOBY-Server Makefile.PL,1.10,1.11 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/11/17 15:25:10 1.10 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:53:11 1.11 @@ -29,6 +29,7 @@ requires 'DBD::mysql' => '0.01'; # used in MobyUnitTest requires 'XML::Simple' => '2.18'; + requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires requires 'WSRF::Lite' => '0.8.2.3'; From kawas at dev.open-bio.org Tue Dec 2 13:53:46 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:53:46 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021853.mB2Irkas006720@dev.open-bio.org> kawas Tue Dec 2 13:53:46 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client In directory dev.open-bio.org:/tmp/cvs-serv6685/Perl/MOBY-Server/lib/MOBY/Client Modified Files: MobyUnitTest.pm Log Message: removed logic used to diff XML doms and instead use a module XML::SemanticCompare to do the diff moby-live/Perl/MOBY-Server/lib/MOBY/Client MobyUnitTest.pm,1.3,1.4 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm 2008/11/25 17:29:54 1.3 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm 2008/12/02 18:53:46 1.4 @@ -10,6 +10,7 @@ use strict; use Carp; +use XML::SemanticCompare; use vars qw /$VERSION/; $VERSION = sprintf "%d.%02d", q$Revision$ =~ /: (\d+)\.(\d+)/; @@ -19,7 +20,6 @@ #----------------------------------------------------------------- # load all modules needed #----------------------------------------------------------------- -use XML::Simple; use XML::LibXML; use Data::Dumper; @@ -150,139 +150,9 @@ sub _test_xml { my ( $self, $xml ) = @_; return undef if $self->expected_output =~ m//g; - - # create object - my $xml_simple = new XML::Simple( - ForceArray => 1, - ForceContent => 1, - - #KeepRoot => 1, - SuppressEmpty => 1, - keyattr => [] - ); - - # read both XML files into a HASH - my $control = undef; - my $test = undef; - - # check for invalid XML - eval { $control = $xml_simple->XMLin( $self->expected_output ); }; - return undef if $@; - # check for invalid XML - eval { $test = $xml_simple->XMLin($xml); }; - return undef if $@; - return $self->_compare_current_level( $control, $test, (), () ); -} - -#----------------------------------------------------------------- -# _compare_current_level: -# compares current level of data structures that represent XML -# documents. -# If the current level and all child levels match, a true value -# is returned. Otherwise, undef is returned. -#----------------------------------------------------------------- -sub _compare_current_level { - - # $control is current level in hash - # x_ns are the prefixes that we use - my ( $self, $control, $test, $control_ns, $test_ns ) = @_; - - # if either hash is missing they arent equal - return undef unless $control; - return undef unless $test; - - # get the namespace prefix and uris at the current level - # for each doc and remove from current level of hash - for my $key ( keys %$control ) { - next unless $key =~ m/^xmlns[:]?/; - $control_ns->{''} = ${$control}->{$key} if $key eq 'xmlns'; - $control_ns->{$1} = ${$control}->{$key} if $key =~ m/xmlns\:(.*)$/g; - delete $$control->{$key}; - } - for my $key ( keys %$test ) { - next unless $key =~ m/^xmlns[:]?/; - $test_ns->{''} = ${$test}->{$key} if $key eq 'xmlns'; - $test_ns->{$1} = ${$test}->{$key} if $key =~ m/xmlns\:(.*)$/g; - delete ${$test}->{$key}; - } - - # compare current level number of keys - return undef unless (keys %$control) == (keys %$test); - - # number of keys are equal, so start comparing! - my $matching_nodes = 0; - for my $key ( keys %$control ) { - my $success = 1; - for my $test_key ( keys %$test ) { - # does the key exist? - # 'content' is a special case ... because its text content for a node - if ( ($key eq $test_key and $key eq 'content' ) - or ($self->_get_prefixed_key( $test_key, $test_ns ) eq - $self->_get_prefixed_key( $key, $control_ns ) - and $self->_get_prefixed_key( $key, $control_ns ))) - { - - # are we dealing with scalar values now or more nesting? - if ( ref( ${$control}->{$key} ) eq 'ARRAY' ) { - # both items should be an array - next unless ref(${$test}->{$test_key}) eq 'ARRAY'; - # array sizes should match here ... - next unless @{${$control}->{$key}} == @{${$test}->{$test_key}}; - # more nesting try matching child nodes - my $child_matches = 0; - foreach my $child ( @{ ${$control}->{$key} } ) { - my $matched = undef; - foreach my $test_child ( @{ ${$test}->{$test_key} } ) { - $matched = $self->_compare_current_level( $child, $test_child, $control_ns, $test_ns ); - $child_matches++ if $matched; - last if $matched; - } # end inner foreach - $matching_nodes++ if @{ ${$control}->{$key} } == $child_matches; - } - } else { - # compare scalar values now - # we dont care about whitespace, so we need to trim the text - my $c_text = $self->_clear_whitespace(${$control}->{$key}); - my $t_text = $self->_clear_whitespace(${$test}->{$test_key}); - $matching_nodes++ if $c_text eq $t_text; - last if $c_text eq $t_text; - } - } - } #end inner for - } - - # no differences found! - return undef unless $matching_nodes == (keys %$control); - return 1; -} - -#----------------------------------------------------------------- -# _clear_whitespace: a whitespace trim function -#----------------------------------------------------------------- -sub _clear_whitespace { - my ($self, $text) = @_; - $text =~ s/^\s+//; - $text =~ s/\s+$//; - return $text; -} - -#----------------------------------------------------------------- -# _get_prefixed_key: -# goes through and tries to determine what the namespace URI -# is for a prefix. -# Once a URI is found, the prefix is swapped with URI and -# returned. -#----------------------------------------------------------------- -sub _get_prefixed_key { - my ( $self, $key, $ns_hash ) = @_; - my $prefixed_key = $key; - my $prefix = $1 if $key =~ m/^([\w]+)\:.*/; - $prefixed_key =~ s/$prefix/$ns_hash->{$prefix}/ if $prefix; - - # check for default xmlns - $prefixed_key = $ns_hash->{$prefix} . ":" . $key - if not $prefix and defined $ns_hash->{$prefix}; - return $prefixed_key; + # compare the docs + my $sc = XML::SemanticCompare->new(); + return $sc->compare($self->expected_output, $xml); } #----------------------------------------------------------------- @@ -295,21 +165,8 @@ # empty xml, nothing to test return undef if $xml =~ m//g; #instantiate a parser - my $parser = XML::LibXML->new(); - my $tree = undef; - # try parsing a string or a file - eval {$tree = $parser->parse_string($xml);}; - eval {$tree = $parser->parse_file($xml);} if $@; - return undef if $@; - my $root = $tree->getDocumentElement; - # evaluate the xpath statement - my $results = undef; - eval {$results = $root->find($self->xpath); }; - return undef if $@; - # no results? - return undef unless $results; - # got some hits! - return 1; + my $sc = XML::SemanticCompare->new(); + return $sc->test_xpath($self->xpath, $xml); } #----------------------------------------------------------------- From kawas at dev.open-bio.org Tue Dec 2 13:54:50 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:54:50 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021854.mB2IsoJ1006760@dev.open-bio.org> kawas Tue Dec 2 13:54:50 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6725/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: update wsrf-lite version that we use (significant bug fixes in newest version of WSRF::Lite) moby-live/Perl/MOBY-Server Makefile.PL,1.11,1.12 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:53:11 1.11 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:54:50 1.12 @@ -32,7 +32,7 @@ requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires - requires 'WSRF::Lite' => '0.8.2.3'; + requires 'WSRF::Lite' => '0.8.2.6'; if ( not( $^O =~ /MSWin32|Windows_NT/i ) ) { From kawas at dev.open-bio.org Tue Dec 2 14:15:02 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:15:02 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021915.mB2JF2jT006885@dev.open-bio.org> kawas Tue Dec 2 14:15:02 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6850/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: fix wsrf version moby-live/Perl/MOBY-Server Makefile.PL,1.12,1.13 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:54:50 1.12 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 19:15:02 1.13 @@ -32,7 +32,7 @@ requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires - requires 'WSRF::Lite' => '0.8.2.6'; + requires 'WSRF::Lite' => '0.8.2.5'; if ( not( $^O =~ /MSWin32|Windows_NT/i ) ) { From kawas at dev.open-bio.org Tue Dec 2 14:15:31 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:15:31 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021915.mB2JFVAS006925@dev.open-bio.org> kawas Tue Dec 2 14:15:31 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6890/Perl/MOBY-Server Modified Files: META.yml Log Message: updated 'requires' moby-live/Perl/MOBY-Server META.yml,1.4,1.5 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml 2008/06/05 14:13:52 1.4 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml 2008/12/02 19:15:31 1.5 @@ -41,4 +41,7 @@ XML::DOM: 0 XML::LibXML: 1.62 XML::XPath: 1.12 -version: 1.05 + XML::SemanticCompare: 0 + XML::Simple: 2.18 + WSRF::Lite: 0.8.2.5 +version: 1.06 From kawas at dev.open-bio.org Tue Dec 2 14:16:19 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:16:19 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021916.mB2JGJoK006965@dev.open-bio.org> kawas Tue Dec 2 14:16:19 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv6930/Perl/MOBY-Client Modified Files: META.yml Log Message: updated 'requires' moby-live/Perl/MOBY-Client META.yml,1.2,1.3 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml 2008/03/05 18:38:40 1.2 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml 2008/12/02 19:16:19 1.3 @@ -23,6 +23,8 @@ SOAP::Lite: 0.60 URI::Escape: 0 XML::LibXML: 0 - WSRF::Lite: 0 + WSRF::Lite: 0.8.2.5 RDF::Core: 0.51 -version: 1.01 + XML::Simple: 2.18 + XML::SemanticCompare: 0.91 +version: 1.03 From kawas at dev.open-bio.org Tue Dec 2 14:16:52 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:16:52 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021916.mB2JGqhL007005@dev.open-bio.org> kawas Tue Dec 2 14:16:52 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv6970/Perl/MOBY-Client Modified Files: Makefile.PL Log Message: updated 'requires' moby-live/Perl/MOBY-Client Makefile.PL,1.9,1.10 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/11/17 15:30:55 1.9 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:16:52 1.10 @@ -21,6 +21,7 @@ requires 'RDF::Core' => '0.51'; # MOBY::Client::MobyUnitTest depends requires 'XML::Simple' => '2.18'; +requires 'XML::SemanticCompare' => '0.91'; # MOBY::CommonSubs depends requires 'HTML::Entities' => 0; From kawas at dev.open-bio.org Tue Dec 2 14:18:31 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:18:31 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021918.mB2JIVUe007087@dev.open-bio.org> kawas Tue Dec 2 14:18:31 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv7052/Perl/MOBY-Client Modified Files: Makefile.PL Log Message: updated wsrf version moby-live/Perl/MOBY-Client Makefile.PL,1.10,1.11 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:16:52 1.10 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:18:31 1.11 @@ -27,7 +27,7 @@ requires 'HTML::Entities' => 0; # MOBY::Async requires -requires 'WSRF::Lite' => '0.8.2.2.3'; +requires 'WSRF::Lite' => '0.8.2.5'; auto_install; From senger at dev.open-bio.org Wed Dec 3 07:22:21 2008 From: senger at dev.open-bio.org (Martin Senger) Date: Wed, 3 Dec 2008 07:22:21 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031222.mB3CMLKI012050@dev.open-bio.org> senger Wed Dec 3 07:22:21 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv12031/S/client Modified Files: CentralImpl.java Log Message: revert to 1.57 moby-live/Java/src/main/org/biomoby/client CentralImpl.java,1.59,1.60 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:09:40 1.59 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:22:21 1.60 @@ -1,2139 +1,2139 @@ -// CentralImpl.java -// A default client to the Moby Central service. -// -// senger at ebi.ac.uk -// February 2003 -// - -package org.biomoby.client; - -import org.biomoby.registry.meta.Registry; -import org.biomoby.shared.Central; -import org.biomoby.shared.MobyData; -import org.biomoby.shared.MobyDataType; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyNamespace; -import org.biomoby.shared.MobyPrimaryDataSet; -import org.biomoby.shared.MobyPrimaryDataSimple; -import org.biomoby.shared.MobyRelationship; -import org.biomoby.shared.MobySecondaryData; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.MobyServiceType; -import org.biomoby.shared.NoSuccessException; -import org.biomoby.shared.PendingCurationException; -import org.biomoby.shared.MobyResourceRef; -import org.biomoby.shared.Utils; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.namespace.QName; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.apache.axis.AxisFault; -import org.apache.axis.client.Call; -import org.apache.axis.client.Service; -import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.methods.HeadMethod; -import org.apache.commons.httpclient.params.HttpMethodParams; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.PrintStream; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Vector; -import java.util.TreeMap; -import java.util.Comparator; -import java.util.zip.GZIPInputStream; -import java.util.logging.*; - -/** - * A default implementation of the - * interface {@link org.biomoby.shared.Central Central} - * allowing access to a Moby registry. - *

- * This class is supposed to be used by all other clients that wish - * to communicate with the Moby Registry, but do not want to know - * about all XML details that are necessary for talking with the Moby Central - * directly. This is an example of a client program: - *

- * import org.biomoby.shared.Central;
- * import org.biomoby.shared.MobyException;
- * import org.biomoby.client.CentralImpl;
- * import java.util.Map;
- * import java.util.Iterator;
- *
- * public class Test {
- *
- *    public static void main (String[] args)
- *       throws MobyException {
- *
- *       Central worker = new CentralImpl();
- *       Map authorities = worker.getServiceNamesByAuthority();
- *
- *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
- *          Map.Entry entry = (Map.Entry)it.next();
- *          System.out.println (entry.getKey());
- *          String[] names = (String[])entry.getValue();
- *          for (int i = 0; i < names.length; i++)
- *             System.out.println ("\t" + names[i]);
- *       }
- *    }
- * }
- *
- * - * @author Martin Senger - * @version $Id$ - */ - -public class CentralImpl - implements Central, SimpleCache { - - private URL endpoint; - private String uri; - protected boolean debug = false; - - /** Common central used to if getDefaultCentral() is called */ - protected static Map defaultCentrals = new HashMap(); - - /** Default location (endpoint) of a Moby registry. */ - public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; - - /** Default namespace used by the contacted Moby registry. */ - public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; - - /** - * The META-INF resource file that will be checked to determine what - * default class should be instantiated in order to create a Central Implementation - * when getDefaultCentral() is called. - */ - public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; - /** The class to use for getDefaultCentral if all else fails */ - public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; - private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); - - /** - * Thread local that gives each thread its own - * DocumentBuilderFactory (since it is not thread-safe). Code taken - * from Apache's JaxpUtils. - */ - public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { - protected synchronized Object initialValue() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware (true); - return dbf; - } - }; - - - /************************************************************************* - * Default constructor. It connects to a default Moby registry - * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace - * (as defined int {@link #DEFAULT_NAMESPACE}). - *************************************************************************/ - public CentralImpl() - throws MobyException { - this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); - } - - /************************************************************************* - * Constructor allowing to specify which Moby Registry to use. - * - * @throws MobyException if 'endpoint' is not a valid URL, or if no - * DOM parser is available - *************************************************************************/ - public CentralImpl (String endpoint) - throws MobyException { - this (endpoint, DEFAULT_NAMESPACE); - } - - /************************************************************************* - * Constructor allowing to specify which Moby Registry and what - * namespace to use. If any of the parameters is null, its default - * value is used instead. - *

- * @throws MobyException if 'endpoint' is not a valid URL, or if no - * DOM parser was found - *************************************************************************/ - public CentralImpl (String endpoint, String namespace) - throws MobyException { - - if (endpoint == null || "".equals (endpoint.trim())) - endpoint = DEFAULT_ENDPOINT; - if (namespace == null || "".equals (namespace.trim())) - namespace = DEFAULT_NAMESPACE; - - try { - this.endpoint = new URL (endpoint); - } catch (MalformedURLException e) { - throw new MobyException ("Bad URL: " + endpoint); - } - this.uri = namespace; - - cache = new Hashtable(); - useCache = true; - } - - /************************************************************************* - * Loads a DOM Document from an InputStream. Uses thread-safe - * mechanism. - *************************************************************************/ - public static Document loadDocument (InputStream input) - throws MobyException { - try { - DocumentBuilderFactory dbf - = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); - DocumentBuilder db = dbf.newDocumentBuilder(); - return (db.parse (input)); - } catch (Exception e) { - throw new MobyException ("Problem with reading XML input: " + e.toString(), e); - } - } - - /************************************************************************* - * Call 'method' with 'parameters' and return its result. - *************************************************************************/ - protected Object doCall (String method, Object[] parameters) - throws MobyException { - - Call call = null; - try { - Service service = new Service(); - call = (Call) service.createCall(); - call.setTargetEndpointAddress (endpoint); - call.setTimeout (new Integer (0)); - - call.setSOAPActionURI (uri + "#" + method); - - if (debug) { - System.err.println ("METHOD CALL: " + method); - System.err.println ("------------"); - if (parameters.length > 0) - System.err.println (parameters[0] + "\n"); - System.err.println ("------------\n"); - - Object result = call.invoke (uri, method, parameters); - - System.err.println ("METHOD RETURN:"); - System.err.println ("------------"); - if (result != null) - System.err.println (result + "\n"); - System.err.println ("------------\n"); - - return resultToString (result); - - } else { - return resultToString (call.invoke (uri, method, parameters)); - } - - } catch (AxisFault e) { - throw new MobyException - (formatFault (e, - endpoint.toString(), - (call == null ? null : call.getOperationName())), - e); -// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); - - } catch (Exception e) { - throw new MobyException (e.toString(), e); -// e.printStackTrace(); - } - } - - - /************************************************************************** - * Parse the given XML sniplet to find tag 'success'. If it has value '1' - * look further for tag 'id' and return it back (or return an empty string - * if ID is not there). Otherwise raise an exception with the 'culprit' - * and with the message from the tag 'message'.

- * - * The return value is a two-element long array. The first element - * is the ID (given by BioMobe registry), and the second element - * is RDF corresponding with the registered object (BioMoby - * returns this only for service instances, so for other objects - * this will be null).

- * - * This is how the XML is supposed to look: - * - * - * - * - * - * - * - * Success takes the value "1" to indicate success, "0" to - * indicate failure, and "-1" to indicate "Pending Curation". - *************************************************************************/ - protected String[] checkRegistration (String xml, Object culprit) - throws MobyException, NoSuccessException, PendingCurationException { - - String id = "", success = "0", message = "", rdf = ""; - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); - Element root = document.getDocumentElement(); - - NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item (i).getNodeType() != Node.ELEMENT_NODE) - continue; - Element elem = (Element)children.item (i); - if (elem.getNodeName().equals ("id")) { - if (elem.getFirstChild() != null) - id = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals("success")) { - if (elem.getFirstChild() != null) - success = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals ("message")) { - if (elem.getFirstChild() != null) - message = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals ("RDF")) { - if (elem.getFirstChild() != null) - rdf = elem.getFirstChild().getNodeValue(); - } - } - - if (success.equals ("0")) - throw new NoSuccessException (message, culprit); - else if (success.equals ("-1")) - throw new PendingCurationException(); - return new String[] { id, rdf }; - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing input - * data types and their usage in the given service. Only data considered - * primary are included. Note that the main job of converting to XML is - * done by instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - * - *************************************************************************/ - protected String buildPrimaryInputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryInputs = service.getPrimaryInputs(); - buf.append ("\n"); - for (int i = 0; i < primaryInputs.length; i++) - buf.append (primaryInputs[i].toXML()); - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing input - * data types and their usage in the given service. Only data considered - * secondary are included. Note that the main job of converting to XML is - * done by instances of MobySecondaryData. - * - * The returned XML looks like this: - * - * - * - *************************************************************************/ - protected String buildSecondaryInputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] secInputs = service.getSecondaryInputs(); - buf.append ("\n"); - for (int i = 0; i < secInputs.length; i++) { - buf.append (secInputs[i].toXML()); - } - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing output - * data types and their usage in the given service. Only data considered - * primary are included. Note that the main job of converting to XML is - * done by instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - * - * - *************************************************************************/ - protected String buildOutputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryOutputs = service.getPrimaryOutputs(); - buf.append ("\n"); - for (int i = 0; i < primaryOutputs.length; i++) - buf.append (primaryOutputs[i].toXML()); - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML represented a query object (an object used - * to find a service). - * - * The returned XML looks like this: - * - * - * - * - * - * - * - * - * - * - * - * ServiceTypeTerm - * ServiceName - * moby - * http://desired.service.provider; - * 1|0 - * 1|0 - * 1|0 - * - * something - * .... - * .... - * - *************************************************************************/ - protected String buildQueryObject (MobyService service, - String[] keywords, - boolean expandObjects, - boolean expandServices, - boolean authoritative) { - if (service == null) { - service = new MobyService ("dummy"); - service.setCategory (""); - } - StringBuffer buf = new StringBuffer(); - - buf.append ("\n\n"); - MobyData[] pi = service.getPrimaryInputs(); - if (pi.length > 0) { - for (int i = 0; i < pi.length; i++) - buf.append (pi[i].toXML()); - } - buf.append ("\n\n"); - - buf.append ("\n\n"); - MobyData[] po = service.getPrimaryOutputs(); - if (po.length > 0) { - for (int i = 0; i < po.length; i++) - buf.append (po[i].toXML()); - } - buf.append ("\n\n"); - - buf.append ("" + service.getType() + "\n"); - - String name = service.getName(); - if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) - buf.append ("" + service.getName() + "\n"); - - String sigURL = service.getSignatureURL(); - if (!sigURL.equals ("")) - buf.append ("" + sigURL + "\n"); - - buf.append ("" + service.getCategory() + "\n"); - buf.append ("" + service.getAuthority() + "\n"); - - buf.append (""); - buf.append (expandObjects ? "1" : "0"); - buf.append ("\n"); - - buf.append (""); - buf.append (expandServices ? "1" : "0"); - buf.append ("\n"); - - buf.append (""); - buf.append (authoritative ? "1" : "0"); - buf.append ("\n"); - - buf.append ("\n"); - if (keywords != null && keywords.length > 0) { - for (int i = 0; i < keywords.length; i++) { - buf.append (""); - buf.append (keywords[i]); - buf.append ("\n"); - } - } - buf.append ("\n"); - - return new String (buf); - } - - /************************************************************************** - * Extract one or more MobyService objects from the given XML piece. - * The XML should look like this: - *

-     *  <Services>
-     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
-     *      <serviceType>Service_Ontology_Term</serviceType>
-     *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
-     *      <contactEmail>your at email.addy.here</contactEmail>
-     *      <signatureURL>http://service.RDF.here</signatureURL>
-     *      <URL>http://service.endpoint.here/scriptname</URL>
-     *      <authoritative>1</authoritative>
-     *      <Input>
-     *           <!-- one or more Simple and/or Complex Primary articles -->
-     *      </Input>
-     *      <Output>
-     *           <!-- one or more Simple and/or Complex Primary articles --> 
-     *      </Output>
-     *      <secondaryArticles>
-     *           <!-- one or more Secondary articles -->
-     *      </secondaryArticles>
-     *      <Description><![CDATA[free text description here]]></Description>
-     *    </Service>
-     *    ...  <!--  one or more Service blocks may be returned -->
-     *    ...
-     *    ...
-     *  </Services>
-     * 
- * @throws MobyException if the XML document is invalid - *************************************************************************/ - public MobyService[] extractServices (String xml) - throws MobyException { - - Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); - NodeList list = document.getElementsByTagName ("Service"); - MobyService[] results = new MobyService [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyService service = new MobyService (elem.getAttribute ("serviceName")); - service.setAuthority (elem.getAttribute ("authURI")); - service.setLSID (elem.getAttribute ("lsid")); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("Description")) { - service.setDescription (getFirstValue (children.item (j))); - } else if (nodeName.equals ("Category")) { - service.setCategory (getFirstValue (children.item (j))); - } else if (nodeName.equals ("URL")) { - service.setURL (getFirstValue (children.item (j))); - } else if (nodeName.equals ("signatureURL")) { - service.setSignatureURL (getFirstValue (children.item (j))); - } else if (nodeName.equals ("contactEmail")) { - service.setEmailContact (getFirstValue (children.item (j))); - } else if (nodeName.equals ("serviceType")) { - service.setType (getFirstValue (children.item (j))); - MobyServiceType mst = new MobyServiceType(service.getType()); - NamedNodeMap map = (children.item (j).getAttributes()); - if (map != null) { - Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); - if (node != null) - mst.setLSID(node.getNodeValue()); - } - service.setServiceType(mst); - } else if (nodeName.equals ("authoritative")) { - String authoritative = getFirstValue (children.item (j)); - service.setAuthoritative (authoritative.equals ("1") ? true : false); - } else if (nodeName.equals ("Input")) { - // - // - // - // ... - // - // - // ...... - // ...... - // - // - NodeList inputs = children.item (j).getChildNodes(); - for (int k = 0; k < inputs.getLength(); k++) { - if (inputs.item (k).getNodeName().equals ("Simple")) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); - service.addInput (data); - } else if (inputs.item (k).getNodeName().equals ("Collection")) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); - service.addInput (data); - } - } - } else if (nodeName.equals ("Output")) { - // - // - // - NodeList inputs = children.item (j).getChildNodes(); - for (int k = 0; k < inputs.getLength(); k++) { - if (inputs.item (k).getNodeName().equals ("Simple")) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); - service.addOutput (data); - } else if (inputs.item (k).getNodeName().equals ("Collection")) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); - service.addOutput (data); - } - } - - } else if (nodeName.equals ("secondaryArticles")) { - // - // ... - // - NodeList parameters = children.item (j).getChildNodes(); - for (int k = 0; k < parameters.getLength(); k++) { - if (parameters.item (k).getNodeName().equals ("Parameter")) { - MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); - service.addInput (data); - } - } - } - } - results [i] = service; - } - return results; - } - - // protect against null values - protected String getFirstValue (Node child) { - Node node = child.getFirstChild(); - if (node == null) return ""; - String value = node.getNodeValue(); - if (value == null) return ""; - return value; - } - - protected String getFirstValue (NodeList children) { - if (children.item(0) != null && children.item(0).hasChildNodes()) { - children.item(0).normalize(); - return getFirstValue (children.item(0)); - } - return ""; - } - - /************************************************************************** - * - * Implementing SimpleCache interface. - * - * Why to have an interface for such trivial thing? Well, because - * I needed to overwrite the caching mechanism in the subclasses - * so I needed to have all caching functions as separate methods - - * that's why I have collect them in an interface. - * - *************************************************************************/ - private Hashtable cache; // this is the cache itself - private boolean useCache; // this signal that we are actually caching things - - // not used here - public String createId (String rootName, - String semanticType, String syntaxType, - long lastModified, - Properties props) { - return ""; // not used here - } - - // check existence of a cached object - public boolean existsInCache (String id) { - synchronized (cache) { - if (useCache) return cache.containsKey (id); - else return false; - } - } - - // retrieve from cache - public Object getContents (String id) { - synchronized (cache) { - if (useCache) return cache.get (id); - else return null; - } - } - - // cache an object - public void setContents (String id, java.lang.Object data) { - synchronized (cache) { - if (useCache) cache.put (id, data); - } - } - - // in this implementation, it clears the whole cache, regardless - // what 'id' is passed - public void removeFromCache (String id) { - cache.clear(); - } - - /************************************************************************** - * - * And the other methods related to caching (but not part of the - * SimpleCache interface). - * - **************************************************************************/ - - /************************************************************************** - * By default, caching is enabled to reduce network traffic. - * Setting this to false will clear the cache, and not cache any - * further calls unless it is set to true again.

- * - * @param shouldCache whether retrieveXXX call results should be - * cached in case they are called again (i.e. don't request - * MobyCentral every time) - **************************************************************************/ - public void setCacheMode (boolean shouldCache) { - useCache = shouldCache; - if (! useCache) - removeFromCache (null); - } - - /************************************************************************** - * Find if caching is currently enabled. - * - * @return true if caching is enabled - **************************************************************************/ - public boolean getCacheMode(){ - return useCache; - } - - /************************************************************************** - * Parses and imports the following XML. - *

-     * <serviceNames>
-     *   <serviceName name="serviceName" authURI='authority.info.here'/>
-     *   ...
-     *   ...
-     * </serviceNames>
-     * 
- * - * @deprecated Replaced by {@link - * #getServiceNamesByAuthority}. The reason is that this method - * returns a random result if there are more services with the - * same name but belonging to different authorities.

- * - *************************************************************************/ - public Map getServiceNames() - throws MobyException { - - String result = (String)doCall ("retrieveServiceNames", - new Object[] {}); - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceName"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - results.put (elem.getAttribute ("name"), - elem.getAttribute ("authURI")); - } - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *

-     * <serviceNames>
-     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
-     *   ...
-     *   ...
-     * </serviceNames>
-     * 
- * - * @return a Map which has authorities as keys, and String arrays - * with service names as a values. - *************************************************************************/ - public Map getServiceNamesByAuthority() - throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML (result, true); - } - - /************************************************************************** - * Similar to {@link #getServiceNamesByAuthority} but the - * resulting Map contains slightly more.

- * - * @return a Map which has authorities as keys, and arrays of - * MobyServices as a values. Each MobyService is filled with its - * name, authority and LSID. - *************************************************************************/ - public Map getServicesByAuthority() - throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML (result, false); - } - - // - protected String getServiceNamesByAuthorityAsXML() - throws MobyException { - return (String)doCall ("retrieveServiceNames", - new Object[] {}); - } - - // if onlyNames == true - // Map: authority name -> String[] - // (filled with service namea) - // else - // Map: authority name -> MobyService[] - // (filled with service name, authority and lsid) - protected Map createServicesByAuthorityFromXML (String result, - boolean onlyNames) - throws MobyException { - - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceName"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String name = elem.getAttribute ("name"); - String auth = elem.getAttribute ("authURI"); - Vector v = - (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); - if (onlyNames) { - v.addElement (name); - } else { - MobyService ms = new MobyService (name); - ms.setAuthority (auth); - ms.setLSID (elem.getAttribute ("lsid")); - v.addElement (ms); - } - results.put (auth, v); - } - - // change values of type Vector to MobyService[] or String[] - for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry)it.next(); - Vector v = (Vector)entry.getValue(); - if (onlyNames) { - String[] sNames = new String [v.size()]; - v.copyInto (sNames); - entry.setValue (sNames); - } else { - MobyService[] mss = new MobyService [v.size()]; - v.copyInto (mss); - entry.setValue (mss); - } - } - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     *  <serviceProviders>
-     *     <serviceProvider name="authority.URI.here"/>
-     *          ...
-     *          ...
-     *  </serviceProviders>
-     * 
- *************************************************************************/ - public String[] getProviders() - throws MobyException { - - String cacheId = "retrieveServiceProviders"; - String[] cachedResults = (String[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = (String)doCall ("retrieveServiceProviders", - new Object[] {}); - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceProvider"); - String[] results = new String [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) - results[i] = ((Element)list.item (i)).getAttribute ("name"); - - // Add this data to the cache in case we get called again - setContents (cacheId, results); - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     *  <serviceTypes>
-     *     <serviceType name="serviceName" lsid="...">
-     *            <Description><![CDATA[free text description here]]></Description>
-     *            <contactEmail>...</contactEmail>
-     *            <authURI>...</authURI>
-     *     </serviceType>
-     *          ...
-     *          ...
-     *  </serviceTypes>
-     * 
- *************************************************************************/ - public Map getServiceTypes() - throws MobyException { - String result = getServiceTypesAsXML(); - Map results = new TreeMap (getStringComparator()); - MobyServiceType[] types = createServiceTypesFromXML (result); - for (int i = 0; i < types.length; i++) { - results.put (types[i].getName(), - types[i].getDescription()); - } - return results; - } - - // - protected String getServiceTypesAsXML() - throws MobyException { - return (String)doCall ("retrieveServiceTypes", - new Object[] {}); - } - - // but be aware that the created MobyServiceTypes are not complete - // - they do not have the relationship information; that's why - // this method is not public; the full service types are available - // from CentralDigest implementations - protected MobyServiceType[] createServiceTypesFromXML (String result) - throws MobyException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceType"); - if (list == null || list.getLength() == 0) - return new MobyServiceType[] {}; - MobyServiceType[] results = new MobyServiceType [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); - st.setLSID (elem.getAttribute ("lsid")); - st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); - st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); - st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); - results[i] = st; - } - java.util.Arrays.sort (results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     *  <Namespaces>
-     *     <Namespace name="namespace" lsid="...">
-     *            <Description><![CDATA[free text description here]]></Description>
-     *            <contactEmail>...</contactEmail>
-     *            <authURI>...</authURI>
-     *     </Namespace>
-     *          ...
-     *          ...
-     *  </Namespaces>
-     * 
- *************************************************************************/ - public MobyNamespace[] getFullNamespaces() - throws MobyException { - - String result = getNamespacesAsXML(); - return createNamespacesFromXML (result); - } - - // - protected String getNamespacesAsXML() - throws MobyException { - return (String)doCall ("retrieveNamespaces", - new Object[] {}); - } - - // - protected MobyNamespace[] createNamespacesFromXML (String result) - throws MobyException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); - if (list == null || list.getLength() == 0) { - return new MobyNamespace[] {}; - } - MobyNamespace[] results = new MobyNamespace [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); - nm.setLSID (elem.getAttribute ("lsid")); - nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); - nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); - nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); - results[i] = nm; - } - - java.util.Arrays.sort (results); - return results; - } - - /************************************************************************** - * - * @deprecated Replaced by {@link #getFullNamespaces} that gives - * more information for the same price.

- *************************************************************************/ - public Map getNamespaces() - throws MobyException { - - Map results = new TreeMap (getStringComparator()); - MobyNamespace[] namespaces = getFullNamespaces(); - for (int i = 0; i < namespaces.length; i++) { - results.put (namespaces[i].getName(), - namespaces[i].getDescription()); - } - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *

-     *  <objectNames>
-     *     <Object name="objectName" lsid="...">
-     *            <Description><![CDATA[free text description here]]></Description>
-     *     </Object>
-     *          ...
-     *          ...
-     *  </objectNames>
-     * 
- *************************************************************************/ - public Map getDataTypeNames() - throws MobyException { - String result = getDataTypeNamesAsXML(); - return createDataTypeNamesFromXML (result, true); - } - - // - protected String getDataTypeNamesAsXML() - throws MobyException { - return (String)doCall ("retrieveObjectNames", - new Object[] {}); - } - - // if onlyNames == true - // Map: data type name -> description (String) - // else - // Map: data type name -> MobyDataType[] - // (filled with name, description, and lsid) - protected Map createDataTypeNamesFromXML (String result, - boolean onlyNames) - throws MobyException { - - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Object"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String name = elem.getAttribute ("name"); - if (name == null) - continue; // ignore no-named data types - String desc = ""; - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("Description")) { - desc = getFirstValue (children.item (j)); - break; - } - } - if (onlyNames) { - results.put (name, desc); - } else { - MobyDataType dt = new MobyDataType (name); - dt.setDescription (desc); - dt.setLSID (elem.getAttribute ("lsid")); - results.put (name, dt); - } - } - return results; - } - - - /************************************************************************** - * Parses and imports the following XML. An example: - * - *
-     * <retrieveObjectDefinition>
-     *   <objectType lsid="...">go_term</objectType>
-     *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
-     *   <authURI>http://www.illuminae.com</authURI>
-     *   <contactEmail>markw at illuminae.com</contactEmail>
-     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
-     *      <objectType articleName=''>urn:lsid:biomoby.org:objectclass:object</objectType>
-     *   </Relationship>
-     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
-     *      <objectType articleName='Term'>urn:lsid:biomoby.org:objectclass:string</objectType>
-     *      <objectType articleName='Definition'>urn:lsid:biomoby.org:objectclass:string</objectType>
-     *   </Relationship>
-     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:has'>
-     *      <objectType articleName='Problems'>urn:lsid:biomoby.org:objectclass:string</objectType>
-     *      <objectType articleName='Issues'>urn:lsid:biomoby.org:objectclass:string</objectType>
-     *   </Relationship>
-     * </retrieveObjectDefinition>
-     * 
- *************************************************************************/ - public MobyDataType getDataType (String dataTypeName) - throws MobyException, NoSuccessException { - - String result = getDataTypeAsXML (dataTypeName); - return createDataTypeFromXML (result, dataTypeName); - } - - public MobyDataType[] getDataTypes() - throws MobyException, NoSuccessException { - Map datatypeMap = getDataTypeNames(); - MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; - int i = 0; - for(String dataTypeName: datatypeMap.keySet()){ - datatypes[i++] = getDataType(dataTypeName); - } - return datatypes; - } - - protected String getDataTypeAsXML (String dataTypeName) - throws MobyException, NoSuccessException { - - return (String)doCall ("retrieveObjectDefinition", - new Object[] { - "" + - "" + dataTypeName + "" + - "" - }); - } - - protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) - throws MobyException, NoSuccessException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); - NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); - if (list == null || list.getLength() == 0) - throw new NoSuccessException ("Data Type name was not found.", - dataTypeName); - MobyDataType data = null; - Element elem = (Element)list.item (0); - NodeList children = elem.getChildNodes(); - - // first find the "real" (LSID-ized) data type name - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("objectType")) { - data = new MobyDataType (getFirstValue (children.item (j))); - data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); - break; - } - } - - // if not found (unprobable) use the name given by the caller - if (data == null) - data = new MobyDataType (dataTypeName); - - // now fill the data type object with the rest of attributes - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("Description")) { - data.setDescription (getFirstValue (children.item (j))); - } else if (nodeName.equals ("authURI")) { - data.setAuthority (getFirstValue (children.item (j))); - } else if (nodeName.equals ("contactEmail")) { - data.setEmailContact (getFirstValue (children.item (j))); - } else if (nodeName.equals ("Relationship")) { - String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); - if (relationshipType.endsWith ("isa")) { - - NodeList parents = children.item (j).getChildNodes(); - for (int k = 0; k < parents.getLength(); k++) { - if (parents.item (k).getNodeName().equals ("objectType")) { - data.addParentName (getFirstValue (parents.item (k))); - } - } - } else if (relationshipType.endsWith ("hasa")) { - - NodeList belows = children.item (j).getChildNodes(); - for (int k = 0; k < belows.getLength(); k++) { - if (belows.item (k).getNodeName().equals ("objectType")) { - data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), - getFirstValue (belows.item (k)), - Central.iHASA ); - } - } - } else if (relationshipType.endsWith ("has")) { - - NodeList belows = children.item (j).getChildNodes(); - for (int k = 0; k < belows.getLength(); k++) { - if (belows.item (k).getNodeName().equals ("objectType")) { - data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), - belows.item (k).getFirstChild().getNodeValue(), - Central.iHAS ); - } - } - } - } - } - return data; - } - - /************************************************************************** - * - *************************************************************************/ - public String getServiceWSDL (String serviceName) - throws MobyException, NoSuccessException { - - Map names = getServiceNames(); - - for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry)it.next(); - if ( ((String)entry.getKey()).equals (serviceName) ) - return getServiceWSDL (serviceName, (String)entry.getValue()); - } - - throw new NoSuccessException ("Service not found.", serviceName); - } - - /************************************************************************** - * - *************************************************************************/ - public String getServiceWSDL (String serviceName, String authority) - throws MobyException, NoSuccessException { - - String cacheId = "getServiceWSDL" + serviceName + ":" + authority; - String cachedResults = (String)getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("retrieveService", - new Object[] { - "" + - "" + - "" - }); - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - Element service = document.getDocumentElement(); - Node wsdl = service.getFirstChild(); - if (wsdl == null) - throw new NoSuccessException ("Service not found OR WSDL is not available.", - serviceName + " (" + authority + ")"); - - String results = wsdl.getNodeValue(); - setContents (cacheId, results); - return results; - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterDataTypeXML (MobyDataType dataType) { - - // build the ISA tag (expressing hierarchy of data types) - String[] names = dataType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < names.length; i++) { - buf.append (""); - buf.append (names[i]); - buf.append (""); - buf.append ("\n"); - } - - // build the HASA/HAS tags (expressing containments of data types) - MobyRelationship[] children = dataType.getChildren(); - StringBuffer buf2 = new StringBuffer(); // for HASA - StringBuffer buf3 = new StringBuffer(); // for HAS - for (int i = 0; i < children.length; i++) { - if (children[i].getRelationshipType() == Central.iHASA) { - buf2.append (""); - buf2.append (children[i].getDataTypeName()); - buf2.append (""); - } else if (children[i].getRelationshipType() == Central.iHAS) { - buf3.append (""); - buf3.append (children[i].getDataTypeName()); - buf3.append (""); - } - } - - return - "" + - "" + dataType.getName() + "" + - "" + - "" + - "" + new String (buf) + - "" + - "" + new String (buf2) + - "" + - "" + new String (buf3) + - "" + - "" + dataType.getAuthority() + "" + - "" + dataType.getEmailContact() + "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerDataType (MobyDataType dataType) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerObjectClass", - new Object[] { getRegisterDataTypeXML (dataType) }); - dataType.setId (checkRegistration (result, dataType)[0]); - } - - /************************************************************************* - * B - *************************************************************************/ - public void unregisterDataType (MobyDataType dataType) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterObjectClass", - new Object[] { - "" + - "" + dataType.getName() + "" + - "" - }); - checkRegistration (result, dataType); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterServiceTypeXML (MobyServiceType serviceType) { - - // build the ISA tag (expressing hierarchy of service types) - String[] names = serviceType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < names.length; i++) { - buf.append (""); - buf.append (names[i]); - buf.append (""); - buf.append ("\n"); - } - - return - "" + - "" + serviceType.getName() + "" + - "" + serviceType.getEmailContact() + "" + - "" + serviceType.getAuthority() + "" + - "" + - "" + - "" + new String (buf) + - "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerServiceType (MobyServiceType serviceType) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerServiceType", - new Object[] { getRegisterServiceTypeXML (serviceType) }); - serviceType.setId (checkRegistration (result, serviceType)[0]); - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterServiceType (MobyServiceType serviceType) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterServiceType", - new Object[] { - "" + - "" + serviceType.getName() + "" + - "" - }); - checkRegistration (result, serviceType); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterNamespaceXML (MobyNamespace namespace) { - return - "" + - "" + namespace.getName() + "" + - "" + namespace.getEmailContact() + "" + - "" + namespace.getAuthority() + "" + - "" + - "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerNamespace (MobyNamespace namespace) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("registerNamespace", - new Object[] { getRegisterNamespaceXML (namespace) }); - namespace.setId (checkRegistration (result, namespace)[0]); - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterNamespace (MobyNamespace namespace) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterNamespace", - new Object[] { - "" + - "" + namespace.getName() + "" + - "" - }); - checkRegistration (result, namespace); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterServiceXML (MobyService service) { - return - "" + - "" + service.getCategory() + "" + - "" + service.getName() + "" + - "" + service.getType() + "" + - "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + - "" + service.getAuthority() + "" + - "" + escapeXML (service.getSignatureURL()) + "" + - "" + escapeXML (service.getURL()) + "" + - "" + service.getEmailContact() + "" + - "" + (service.isAuthoritative() ? "1" : "0") + "" + - "" + - "" + - buildPrimaryInputTag (service) + - buildSecondaryInputTag (service) + - buildOutputTag (service) + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerService (MobyService service) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerService", - new Object[] { getRegisterServiceXML (service) }); - String[] registered = checkRegistration (result, service); - service.setId (registered [0]); - service.setRDF (registered [1]); - String pathToRDF = service.getPathToRDF(); - if ( ! pathToRDF.equals ("") ) { - File fileRDF = new File (pathToRDF); - try { - PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); - fileout.println (registered [1]); - fileout.close(); - } catch (IOException e) { - StringBuffer buf = new StringBuffer (100); - buf.append ("Failed to save RDF in '"); - buf.append (fileRDF.getAbsolutePath() + "'. "); - buf.append (e.toString()); - try { - File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); - PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); - fileout.println (registered [1]); - fileout.close(); - buf.append ("\nReturned RDF file was therefore stored in: "); - buf.append (tmpFile.getAbsolutePath()); - } catch (IOException e2) { - buf.append ("\nEven saving in a temporary file failed: "); - buf.append (e2.toString()); - } - throw new MobyException (buf.toString()); - } - } - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterService (MobyService service) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterService", - new Object[] { - "" + - "" + service.getAuthority() + "" + - "" + service.getName() + "" + - "" - }); - checkRegistration (result, service); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (String serviceType) - throws MobyException { - if (serviceType == null) - return new MobyService[] {}; - MobyService pattern = new MobyService ("dummy"); - pattern.setCategory (""); - pattern.setType (serviceType); - return findService (pattern, null); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (String[] keywords) - throws MobyException { - if (keywords == null) - return new MobyService[] {}; - return findService (null, keywords); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (MobyService pattern) - throws MobyException { - if (pattern == null) - return new MobyService[] {}; - return findService (pattern, null); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (MobyService pattern, String[] keywords) - throws MobyException { - return findService (pattern, keywords, true, true); - } - - /************************************************************************** - * All 'findService' methods end up here. - *************************************************************************/ - public MobyService[] findService (MobyService pattern, String[] keywords, - boolean includeChildrenServiceTypes, - boolean includeParentDataTypes) - throws MobyException { - if (pattern == null) { - pattern = new MobyService ("dummy"); - pattern.setCategory (""); - } - - String result = - getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); - MobyService[] services = extractServices (result); - return services; - } - - // ...actually all 'findService' methods end up here - protected String getServicesAsXML (MobyService pattern, String[] keywords, - boolean includeChildrenServiceTypes, - boolean includeParentDataTypes) - throws MobyException { - String[] query = new String[] { - "" + - buildQueryObject (pattern, keywords, - includeParentDataTypes, - includeChildrenServiceTypes, - false) + - "" - }; - return (String)doCall ("findService", query); - } - - /************************************************************************** - * - *************************************************************************/ - public String call (String methodName, String inputXML) - throws MobyException { - Object result; - if (inputXML == null || inputXML.equals ("")) - result = doCall (methodName, new Object[] { }); - else - result = doCall (methodName, new Object[] { inputXML }); - return (String)result; - } - - /************************************************************************** - * - *************************************************************************/ - protected static String resultToString (Object result) - throws MobyException { - if (result == null) - throw new MobyException ("Returned result is null."); - if (result instanceof String) - return (String)result; - if (result instanceof String[]) { - String[] tmp = (String[])result; - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < tmp.length; i++) - buf.append (tmp[i]); - return new String (buf); - } - if (result instanceof byte[]) - return new String ((byte[])result); - - throw new MobyException ("Unknown type of result: " + result.getClass().getName()); - } - - /************************************************************************** - * - *************************************************************************/ - public boolean setDebug (boolean enabled) { - boolean oldMode = debug; - debug = enabled; - return oldMode; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     * <Relationships>
-     *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
-     *     <serviceType>urn:lsid:biomoby.org:servicetype:analysis</serviceType>
-     *     <serviceType>urn:lsid:biomoby.org:servicetype:service</serviceType>
-     *   </Relationship>
-     * </Relationships>
-     * 
- *************************************************************************/ - public String[] getServiceTypeRelationships (String serviceTypeName, - boolean expand) - throws MobyException { - String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); - return createServiceTypeRelationshipsFromXML (result); - } - - // - protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, - boolean expand) - throws MobyException { - return - (String)doCall ("Relationships", - new Object[] { - "" + - "" + serviceTypeName + "" + - "" + Central.ISA + "" + - "" + (expand ? "1" : "0") + "" + - "" - }); - } - - // - protected String[] createServiceTypeRelationshipsFromXML (String result) - throws MobyException { - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("serviceType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - } - String[] results = new String [v.size()]; - v.copyInto (results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     *<Relationships>
-     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
-     *  </Relationship>
-     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
-     *  </Relationship>
-     *</Relationships>
-     * 
- * - * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an - * attributes 'lsid' and 'articleName' in <objectType> element. - *************************************************************************/ - public Map getDataTypeRelationships (String dataTypeName) - throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName; - Map cachedResults = (Map)getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("Relationships", - new Object[] { - "" + - "" + dataTypeName + "" + - "" + Central.ISA + "" + - "" + Central.HASA + "" + - "" + Central.HAS + "" + - "1" + - "" - }); - - // parse returned XML - Map results = new HashMap(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String relType = elem.getAttribute ("relationshipType"); - NodeList children = elem.getChildNodes(); - Vector v = new Vector(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("objectType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - String[] names = new String [v.size()]; - v.copyInto (names); - results.put (relType, names); - } - - setContents (cacheId, results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     *<Relationships>
-     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
-     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
-     *  </Relationship>
-     *</Relationships>
-     * 
- *************************************************************************/ - public String[] getDataTypeRelationships (String dataTypeName, - String relationshipType) - throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; - String[] cachedResults = (String[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("Relationships", - new Object[] { - "" + - "" + dataTypeName + "" + - "" + relationshipType + "" + - "1" + - "" - }); - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - - // it should always be just one element in this list - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("objectType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - } - String[] results = new String [v.size()]; - v.copyInto (results); - - setContents (cacheId, results); - return results; - } - -// /************************************************************************** -// * -// *************************************************************************/ -// public MobyRelationship[] getRelationships (String dataTypeName) -// throws MobyException { -// return null; -// } - - - /************************************************************************** - * - *************************************************************************/ - public String getRegistryEndpoint() { - return endpoint.toString(); - } - - /************************************************************************** - * - *************************************************************************/ - public String getRegistryNamespace() { - return uri; - } - - /************************************************************************** - * Parses and imports the following XML. - *
-     * <resourceURLs>
-     *   <Resource name="Service"         url="..." />
-     *   <Resource name="Object"          url="..." />
-     *   <Resource name="Namespace"       url="..." />
-     *   <Resource name="ServiceInstance" url="..." />
-     *   <Resource name="Full"            url="..." />
-     * </resourceURLs>
-     * 
- *************************************************************************/ - public MobyResourceRef[] getResourceRefs() - throws MobyException { - - String cacheId = "retrieveResourceURLs"; - MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = (String)doCall ("retrieveResourceURLs", - new Object[] {}); - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Resource"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - try { - v.addElement - (new MobyResourceRef (elem.getAttribute ("name"), - new URL ((String)elem.getAttribute ("url")), - elem.getAttribute ("type"))); - } catch (MalformedURLException e2) { - if (debug) - System.err.println ("Bad URL: " + elem.getAttribute ("url")); - } - } - - MobyResourceRef[] results = new MobyResourceRef [v.size()]; - v.copyInto (results); - - // Add this data to the cache in case we get called again - setContents (cacheId, results); - - return results; - } - - /************************************************************************** - * - *************************************************************************/ - public InputStream getResource (String resourceName) - throws MobyException { - - MobyResourceRef[] resourceRefs = getResourceRefs(); - for (int i = 0; i < resourceRefs.length; i++) { - if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { - return Utils.getInputStream (resourceRefs[i].getResourceLocation()); - } - } - throw new MobyException ("No resource found for '" + resourceName + "'."); - } - - /************************************************************************** - * Return a case-insensitive comparator of Strings. It is used to - * create various TreeMaps where keys are strings. - *************************************************************************/ - protected static Comparator getStringComparator() { - return new Comparator() { - public int compare (Object o1, Object o2) { - return ((String)o1).compareToIgnoreCase ((String)o2); - } - }; - } - - // cache URL/URI so we only check once - private static String CHECKED_URL = null; - private static String CHECKED_URI = null; - - /** - * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared - * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods - * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. - * - * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism - */ - public static CentralImpl getDefaultCentral() throws MobyException{ - return getDefaultCentral(null); - } - - public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ - if(reg == null && defaultCentrals.containsKey("")){ - return defaultCentrals.get(""); - } - else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ - return defaultCentrals.get(reg.getEndpoint()); - } - - String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); - if(resURL != null){ - System.err.println("Loading "+resURL); - try{ - LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); - for(String line = reader.readLine(); line != null; line = reader.readLine()){ - if(!line.trim().startsWith("#")){ - className = line.trim(); - break; - } - } - } catch(Exception e){ - logger.log(Level.WARNING, - "Error reading " + resURL, - e); - } - } - try{ - System.err.println("Central class is "+className); - Class clazz = Class.forName(className); - if(reg == null){ // should use default nullary c-tor - defaultCentrals.put("", (CentralImpl) clazz.newInstance()); - } - else{ // should have (String endpoint, String namespace) c-tor - for(Constructor ctor: clazz.getDeclaredConstructors()){ - Class[] params = ctor.getParameterTypes(); - if(params.length == 2 && params[0].getName().equals("java.lang.String") && - params[1].getName().equals("java.lang.String") ){ - defaultCentrals.put(reg.getEndpoint(), - (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); - break; - } - } - if(!defaultCentrals.containsKey(reg.getEndpoint())){ - logger.log(Level.WARNING, - "Could not find required (String endpoint, String namespace)" + - "constructor for class " + className); - } - } - } catch(Exception e){ - logger.log(Level.WARNING, - "Could not load class " + className, - e); - if(reg == null){ - defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. - } - else{ - defaultCentrals.put(reg.getEndpoint(), - new CentralImpl(reg.getEndpoint(), reg.getNamespace())); - } - } - - return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); - } - - /** - * - * @return a String representing the Default mobycentral endpoint. If the - * system property 'moby.check.default' exists and is set to true, - * then the URL http://biomoby.org/mobycentral is queried and the - * default central endpoint is returned, otherwise DEFAULT_ENDPOINT - * is returned. - */ - public static String getDefaultURL() { - boolean check = false; - try { - check = Boolean.getBoolean("moby.check.default"); - } catch (Exception e) { - - } - - if (check) { - // return the last checked url if we have done this before - if (CHECKED_URL != null && CHECKED_URL.trim() != "") { - return CHECKED_URL; - } - - // create a HttpClient object - HttpClient client = new HttpClient(); - // set up the Head method - HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); - // do not follow redirects or we will get a 411 error - method.setFollowRedirects(false); - // retry 3 times - method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); - // set the user agent ... should probably make this something more reasonable - method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); - try { - // Execute the method. - int statusCode = client.executeMethod(method); - - if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { - System.err.println("Method failed: " - + method.getStatusLine()); - } else { - try { - String location = method.getResponseHeader("location").getValue(); - CHECKED_URL = location; - try { - CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; - } catch (MalformedURLException murle ) { - CHECKED_URI = DEFAULT_NAMESPACE; - } - return CHECKED_URL; - } catch (NullPointerException npe) { - return DEFAULT_ENDPOINT; - } - } - } catch (HttpException e) { - System.err.println("Fatal protocol violation: " - + e.getMessage()); - e.printStackTrace(); - } catch (IOException e) { - System.err.println("Fatal transport error: " + e.getMessage()); - e.printStackTrace(); - } finally { - // Release the connection. - method.releaseConnection(); - } - - } else { - return DEFAULT_ENDPOINT; - } - return DEFAULT_ENDPOINT; - } - - /** - * - * @return a String representing the default mobycentral uri. If the - * system property 'moby.check.default' exists and is set to true, - * then the URL http://biomoby.org/mobycentral is queried and the - * default central namespace is returned, otherwise DEFAULT_NAMESPACE - * is returned. - */ - public static String getDefaultURI() { - boolean check = false; - try { - check = Boolean.getBoolean("moby.check.default"); - } catch (Exception e) { - - } - if (check) { - if (CHECKED_URI != null && CHECKED_URI.trim() != "") { - return CHECKED_URI; - } - // need to check ... - getDefaultURL(); - return CHECKED_URI; - } else { - return DEFAULT_NAMESPACE; - } - } - /************************************************************************** - * Convert non-suitable characters in a XML string into their - * entity references.

- * - * Adapted from jDom. - * - * @param str input to be converted - * @return If there were any non-suitable characters, return a new - * string with those characters escaped, otherwise return the - * unmodified input string - * - *************************************************************************/ - public String escapeXML (String str) { - StringBuffer buffer = null; - char ch; - String entity; - for (int i = 0; i < str.length(); i++) { - ch = str.charAt (i); - switch (ch) { - case '<' : - entity = "<"; - break; - case '>' : - entity = ">"; - break; - case '&' : - entity = "&"; - break; - default : - entity = null; - break; - } - if (buffer == null) { - if (entity != null) { - // An entity occurred, so we'll have to use StringBuffer - // (allocate room for it plus a few more entities). - buffer = new StringBuffer (str.length() + 20); - // Copy previous skipped characters and fall through - // to pickup current character - buffer.append (str.substring (0, i)); - buffer.append (entity); - } - } else { - if (entity == null) { - buffer.append (ch); - } else { - buffer.append (entity); - } - } - } - - // If there were any entities, return the escaped characters - // that we put in the StringBuffer. Otherwise, just return - // the unmodified input string. - return (buffer == null) ? str : buffer.toString(); - } - - /************************************************************************* - * Format an exception. - *************************************************************************/ - public static String formatFault (AxisFault e, String endpoint, QName method) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - formatFault (e, new PrintStream (baos), endpoint, method); - return baos.toString(); - } - - /************************************************************************* - * Format an exception. - *************************************************************************/ - public static void formatFault (AxisFault e, PrintStream out, - String endpoint, QName method) { - - out.println ("===ERROR==="); - out.println ("Fault details:"); - // for some obvious errors I do not print all details (with a lenghty trace stack) - String faultString = e.getFaultString(); - if ( (! faultString.startsWith ("java.net.ConnectException")) && - (faultString.indexOf ("Could not find class for the service named:") == -1) - ) { - org.w3c.dom.Element[] details = e.getFaultDetails(); - for (int i = 0; i < details.length; i++) { - String s = details[i].toString().replaceAll ("<", "<"); - s = s.replaceAll (">", ">"); - out.println (s); - } - } - out.println ("Fault string: " + faultString); - out.println ("Fault code: " + e.getFaultCode()); - out.println ("Fault actor: " + e.getFaultActor()); - if (endpoint != null || method != null) - out.println ("When calling:"); - if (endpoint != null) - out.println ("\t" + endpoint); - if (method != null) - out.println ("\t" + method); - out.println ("==========="); - } - - -} +// CentralImpl.java +// A default client to the Moby Central service. +// +// senger at ebi.ac.uk +// February 2003 +// + +package org.biomoby.client; + +import org.biomoby.registry.meta.Registry; +import org.biomoby.shared.Central; +import org.biomoby.shared.MobyData; +import org.biomoby.shared.MobyDataType; +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyNamespace; +import org.biomoby.shared.MobyPrimaryDataSet; +import org.biomoby.shared.MobyPrimaryDataSimple; +import org.biomoby.shared.MobyRelationship; +import org.biomoby.shared.MobySecondaryData; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.MobyServiceType; +import org.biomoby.shared.NoSuccessException; +import org.biomoby.shared.PendingCurationException; +import org.biomoby.shared.MobyResourceRef; +import org.biomoby.shared.Utils; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.namespace.QName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.axis.AxisFault; +import org.apache.axis.client.Call; +import org.apache.axis.client.Service; +import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.HeadMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PrintStream; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; +import java.util.TreeMap; +import java.util.Comparator; +import java.util.zip.GZIPInputStream; +import java.util.logging.*; + +/** + * A default implementation of the + * interface {@link org.biomoby.shared.Central Central} + * allowing access to a Moby registry. + *

+ * This class is supposed to be used by all other clients that wish + * to communicate with the Moby Registry, but do not want to know + * about all XML details that are necessary for talking with the Moby Central + * directly. This is an example of a client program: + *

+ * import org.biomoby.shared.Central;
+ * import org.biomoby.shared.MobyException;
+ * import org.biomoby.client.CentralImpl;
+ * import java.util.Map;
+ * import java.util.Iterator;
+ *
+ * public class Test {
+ *
+ *    public static void main (String[] args)
+ *       throws MobyException {
+ *
+ *       Central worker = new CentralImpl();
+ *       Map authorities = worker.getServiceNamesByAuthority();
+ *
+ *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
+ *          Map.Entry entry = (Map.Entry)it.next();
+ *          System.out.println (entry.getKey());
+ *          String[] names = (String[])entry.getValue();
+ *          for (int i = 0; i < names.length; i++)
+ *             System.out.println ("\t" + names[i]);
+ *       }
+ *    }
+ * }
+ *
+ * + * @author Martin Senger + * @version $Id$ + */ + +public class CentralImpl + implements Central, SimpleCache { + + private URL endpoint; + private String uri; + protected boolean debug = false; + + /** Common central used to if getDefaultCentral() is called */ + protected static Map defaultCentrals = new HashMap(); + + /** Default location (endpoint) of a Moby registry. */ + public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; + + /** Default namespace used by the contacted Moby registry. */ + public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; + + /** + * The META-INF resource file that will be checked to determine what + * default class should be instantiated in order to create a Central Implementation + * when getDefaultCentral() is called. + */ + public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; + /** The class to use for getDefaultCentral if all else fails */ + public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; + private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); + + /** + * Thread local that gives each thread its own + * DocumentBuilderFactory (since it is not thread-safe). Code taken + * from Apache's JaxpUtils. + */ + public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { + protected synchronized Object initialValue() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware (true); + return dbf; + } + }; + + + /************************************************************************* + * Default constructor. It connects to a default Moby registry + * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace + * (as defined int {@link #DEFAULT_NAMESPACE}). + *************************************************************************/ + public CentralImpl() + throws MobyException { + this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry to use. + * + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser is available + *************************************************************************/ + public CentralImpl (String endpoint) + throws MobyException { + this (endpoint, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry and what + * namespace to use. If any of the parameters is null, its default + * value is used instead. + *

+ * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser was found + *************************************************************************/ + public CentralImpl (String endpoint, String namespace) + throws MobyException { + + if (endpoint == null || "".equals (endpoint.trim())) + endpoint = DEFAULT_ENDPOINT; + if (namespace == null || "".equals (namespace.trim())) + namespace = DEFAULT_NAMESPACE; + + try { + this.endpoint = new URL (endpoint); + } catch (MalformedURLException e) { + throw new MobyException ("Bad URL: " + endpoint); + } + this.uri = namespace; + + cache = new Hashtable(); + useCache = true; + } + + /************************************************************************* + * Loads a DOM Document from an InputStream. Uses thread-safe + * mechanism. + *************************************************************************/ + public static Document loadDocument (InputStream input) + throws MobyException { + try { + DocumentBuilderFactory dbf + = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); + DocumentBuilder db = dbf.newDocumentBuilder(); + return (db.parse (input)); + } catch (Exception e) { + throw new MobyException ("Problem with reading XML input: " + e.toString(), e); + } + } + + /************************************************************************* + * Call 'method' with 'parameters' and return its result. + *************************************************************************/ + protected Object doCall (String method, Object[] parameters) + throws MobyException { + + Call call = null; + try { + Service service = new Service(); + call = (Call) service.createCall(); + call.setTargetEndpointAddress (endpoint); + call.setTimeout (new Integer (0)); + + call.setSOAPActionURI (uri + "#" + method); + + if (debug) { + System.err.println ("METHOD CALL: " + method); + System.err.println ("------------"); + if (parameters.length > 0) + System.err.println (parameters[0] + "\n"); + System.err.println ("------------\n"); + + Object result = call.invoke (uri, method, parameters); + + System.err.println ("METHOD RETURN:"); + System.err.println ("------------"); + if (result != null) + System.err.println (result + "\n"); + System.err.println ("------------\n"); + + return resultToString (result); + + } else { + return resultToString (call.invoke (uri, method, parameters)); + } + + } catch (AxisFault e) { + throw new MobyException + (formatFault (e, + endpoint.toString(), + (call == null ? null : call.getOperationName())), + e); +// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); + + } catch (Exception e) { + throw new MobyException (e.toString(), e); +// e.printStackTrace(); + } + } + + + /************************************************************************** + * Parse the given XML sniplet to find tag 'success'. If it has value '1' + * look further for tag 'id' and return it back (or return an empty string + * if ID is not there). Otherwise raise an exception with the 'culprit' + * and with the message from the tag 'message'.

+ * + * The return value is a two-element long array. The first element + * is the ID (given by BioMobe registry), and the second element + * is RDF corresponding with the registered object (BioMoby + * returns this only for service instances, so for other objects + * this will be null).

+ * + * This is how the XML is supposed to look: + * + * + * + * + * + * + * + * Success takes the value "1" to indicate success, "0" to + * indicate failure, and "-1" to indicate "Pending Curation". + *************************************************************************/ + protected String[] checkRegistration (String xml, Object culprit) + throws MobyException, NoSuccessException, PendingCurationException { + + String id = "", success = "0", message = "", rdf = ""; + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + Element root = document.getDocumentElement(); + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item (i).getNodeType() != Node.ELEMENT_NODE) + continue; + Element elem = (Element)children.item (i); + if (elem.getNodeName().equals ("id")) { + if (elem.getFirstChild() != null) + id = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals("success")) { + if (elem.getFirstChild() != null) + success = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("message")) { + if (elem.getFirstChild() != null) + message = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("RDF")) { + if (elem.getFirstChild() != null) + rdf = elem.getFirstChild().getNodeValue(); + } + } + + if (success.equals ("0")) + throw new NoSuccessException (message, culprit); + else if (success.equals ("-1")) + throw new PendingCurationException(); + return new String[] { id, rdf }; + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildPrimaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryInputs = service.getPrimaryInputs(); + buf.append ("\n"); + for (int i = 0; i < primaryInputs.length; i++) + buf.append (primaryInputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * secondary are included. Note that the main job of converting to XML is + * done by instances of MobySecondaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildSecondaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] secInputs = service.getSecondaryInputs(); + buf.append ("\n"); + for (int i = 0; i < secInputs.length; i++) { + buf.append (secInputs[i].toXML()); + } + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing output + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + * + *************************************************************************/ + protected String buildOutputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryOutputs = service.getPrimaryOutputs(); + buf.append ("\n"); + for (int i = 0; i < primaryOutputs.length; i++) + buf.append (primaryOutputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML represented a query object (an object used + * to find a service). + * + * The returned XML looks like this: + * + * + * + * + * + * + * + * + * + * + * + * ServiceTypeTerm + * ServiceName + * moby + * http://desired.service.provider; + * 1|0 + * 1|0 + * 1|0 + * + * something + * .... + * .... + * + *************************************************************************/ + protected String buildQueryObject (MobyService service, + String[] keywords, + boolean expandObjects, + boolean expandServices, + boolean authoritative) { + if (service == null) { + service = new MobyService ("dummy"); + service.setCategory (""); + } + StringBuffer buf = new StringBuffer(); + + buf.append ("\n\n"); + MobyData[] pi = service.getPrimaryInputs(); + if (pi.length > 0) { + for (int i = 0; i < pi.length; i++) + buf.append (pi[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("\n\n"); + MobyData[] po = service.getPrimaryOutputs(); + if (po.length > 0) { + for (int i = 0; i < po.length; i++) + buf.append (po[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("" + service.getType() + "\n"); + + String name = service.getName(); + if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) + buf.append ("" + service.getName() + "\n"); + + String sigURL = service.getSignatureURL(); + if (!sigURL.equals ("")) + buf.append ("" + sigURL + "\n"); + + buf.append ("" + service.getCategory() + "\n"); + buf.append ("" + service.getAuthority() + "\n"); + + buf.append (""); + buf.append (expandObjects ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (expandServices ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (authoritative ? "1" : "0"); + buf.append ("\n"); + + buf.append ("\n"); + if (keywords != null && keywords.length > 0) { + for (int i = 0; i < keywords.length; i++) { + buf.append (""); + buf.append (keywords[i]); + buf.append ("\n"); + } + } + buf.append ("\n"); + + return new String (buf); + } + + /************************************************************************** + * Extract one or more MobyService objects from the given XML piece. + * The XML should look like this: + *

+     *  <Services>
+     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
+     *      <serviceType>Service_Ontology_Term</serviceType>
+     *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
+     *      <contactEmail>your at email.addy.here</contactEmail>
+     *      <signatureURL>http://service.RDF.here</signatureURL>
+     *      <URL>http://service.endpoint.here/scriptname</URL>
+     *      <authoritative>1</authoritative>
+     *      <Input>
+     *           <!-- one or more Simple and/or Complex Primary articles -->
+     *      </Input>
+     *      <Output>
+     *           <!-- one or more Simple and/or Complex Primary articles --> 
+     *      </Output>
+     *      <secondaryArticles>
+     *           <!-- one or more Secondary articles -->
+     *      </secondaryArticles>
+     *      <Description><![CDATA[free text description here]]></Description>
+     *    </Service>
+     *    ...  <!--  one or more Service blocks may be returned -->
+     *    ...
+     *    ...
+     *  </Services>
+     * 
+ * @throws MobyException if the XML document is invalid + *************************************************************************/ + public MobyService[] extractServices (String xml) + throws MobyException { + + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + NodeList list = document.getElementsByTagName ("Service"); + MobyService[] results = new MobyService [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyService service = new MobyService (elem.getAttribute ("serviceName")); + service.setAuthority (elem.getAttribute ("authURI")); + service.setLSID (elem.getAttribute ("lsid")); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + service.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Category")) { + service.setCategory (getFirstValue (children.item (j))); + } else if (nodeName.equals ("URL")) { + service.setURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("signatureURL")) { + service.setSignatureURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + service.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("serviceType")) { + service.setType (getFirstValue (children.item (j))); + MobyServiceType mst = new MobyServiceType(service.getType()); + NamedNodeMap map = (children.item (j).getAttributes()); + if (map != null) { + Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); + if (node != null) + mst.setLSID(node.getNodeValue()); + } + service.setServiceType(mst); + } else if (nodeName.equals ("authoritative")) { + String authoritative = getFirstValue (children.item (j)); + service.setAuthoritative (authoritative.equals ("1") ? true : false); + } else if (nodeName.equals ("Input")) { + // + // + // + // ... + // + // + // ...... + // ...... + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addInput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addInput (data); + } + } + } else if (nodeName.equals ("Output")) { + // + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addOutput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addOutput (data); + } + } + + } else if (nodeName.equals ("secondaryArticles")) { + // + // ... + // + NodeList parameters = children.item (j).getChildNodes(); + for (int k = 0; k < parameters.getLength(); k++) { + if (parameters.item (k).getNodeName().equals ("Parameter")) { + MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); + service.addInput (data); + } + } + } + } + results [i] = service; + } + return results; + } + + // protect against null values + protected String getFirstValue (Node child) { + Node node = child.getFirstChild(); + if (node == null) return ""; + String value = node.getNodeValue(); + if (value == null) return ""; + return value; + } + + protected String getFirstValue (NodeList children) { + if (children.item(0) != null && children.item(0).hasChildNodes()) { + children.item(0).normalize(); + return getFirstValue (children.item(0)); + } + return ""; + } + + /************************************************************************** + * + * Implementing SimpleCache interface. + * + * Why to have an interface for such trivial thing? Well, because + * I needed to overwrite the caching mechanism in the subclasses + * so I needed to have all caching functions as separate methods - + * that's why I have collect them in an interface. + * + *************************************************************************/ + private Hashtable cache; // this is the cache itself + private boolean useCache; // this signal that we are actually caching things + + // not used here + public String createId (String rootName, + String semanticType, String syntaxType, + long lastModified, + Properties props) { + return ""; // not used here + } + + // check existence of a cached object + public boolean existsInCache (String id) { + synchronized (cache) { + if (useCache) return cache.containsKey (id); + else return false; + } + } + + // retrieve from cache + public Object getContents (String id) { + synchronized (cache) { + if (useCache) return cache.get (id); + else return null; + } + } + + // cache an object + public void setContents (String id, java.lang.Object data) { + synchronized (cache) { + if (useCache) cache.put (id, data); + } + } + + // in this implementation, it clears the whole cache, regardless + // what 'id' is passed + public void removeFromCache (String id) { + cache.clear(); + } + + /************************************************************************** + * + * And the other methods related to caching (but not part of the + * SimpleCache interface). + * + **************************************************************************/ + + /************************************************************************** + * By default, caching is enabled to reduce network traffic. + * Setting this to false will clear the cache, and not cache any + * further calls unless it is set to true again.

+ * + * @param shouldCache whether retrieveXXX call results should be + * cached in case they are called again (i.e. don't request + * MobyCentral every time) + **************************************************************************/ + public void setCacheMode (boolean shouldCache) { + useCache = shouldCache; + if (! useCache) + removeFromCache (null); + } + + /************************************************************************** + * Find if caching is currently enabled. + * + * @return true if caching is enabled + **************************************************************************/ + public boolean getCacheMode(){ + return useCache; + } + + /************************************************************************** + * Parses and imports the following XML. + *

+     * <serviceNames>
+     *   <serviceName name="serviceName" authURI='authority.info.here'/>
+     *   ...
+     *   ...
+     * </serviceNames>
+     * 
+ * + * @deprecated Replaced by {@link + * #getServiceNamesByAuthority}. The reason is that this method + * returns a random result if there are more services with the + * same name but belonging to different authorities.

+ * + *************************************************************************/ + public Map getServiceNames() + throws MobyException { + + String result = (String)doCall ("retrieveServiceNames", + new Object[] {}); + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + results.put (elem.getAttribute ("name"), + elem.getAttribute ("authURI")); + } + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *

+     * <serviceNames>
+     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
+     *   ...
+     *   ...
+     * </serviceNames>
+     * 
+ * + * @return a Map which has authorities as keys, and String arrays + * with service names as a values. + *************************************************************************/ + public Map getServiceNamesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, true); + } + + /************************************************************************** + * Similar to {@link #getServiceNamesByAuthority} but the + * resulting Map contains slightly more.

+ * + * @return a Map which has authorities as keys, and arrays of + * MobyServices as a values. Each MobyService is filled with its + * name, authority and LSID. + *************************************************************************/ + public Map getServicesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, false); + } + + // + protected String getServiceNamesByAuthorityAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceNames", + new Object[] {}); + } + + // if onlyNames == true + // Map: authority name -> String[] + // (filled with service namea) + // else + // Map: authority name -> MobyService[] + // (filled with service name, authority and lsid) + protected Map createServicesByAuthorityFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + String auth = elem.getAttribute ("authURI"); + Vector v = + (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); + if (onlyNames) { + v.addElement (name); + } else { + MobyService ms = new MobyService (name); + ms.setAuthority (auth); + ms.setLSID (elem.getAttribute ("lsid")); + v.addElement (ms); + } + results.put (auth, v); + } + + // change values of type Vector to MobyService[] or String[] + for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + Vector v = (Vector)entry.getValue(); + if (onlyNames) { + String[] sNames = new String [v.size()]; + v.copyInto (sNames); + entry.setValue (sNames); + } else { + MobyService[] mss = new MobyService [v.size()]; + v.copyInto (mss); + entry.setValue (mss); + } + } + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     *  <serviceProviders>
+     *     <serviceProvider name="authority.URI.here"/>
+     *          ...
+     *          ...
+     *  </serviceProviders>
+     * 
+ *************************************************************************/ + public String[] getProviders() + throws MobyException { + + String cacheId = "retrieveServiceProviders"; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveServiceProviders", + new Object[] {}); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceProvider"); + String[] results = new String [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) + results[i] = ((Element)list.item (i)).getAttribute ("name"); + + // Add this data to the cache in case we get called again + setContents (cacheId, results); + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     *  <serviceTypes>
+     *     <serviceType name="serviceName" lsid="...">
+     *            <Description><![CDATA[free text description here]]></Description>
+     *            <contactEmail>...</contactEmail>
+     *            <authURI>...</authURI>
+     *     </serviceType>
+     *          ...
+     *          ...
+     *  </serviceTypes>
+     * 
+ *************************************************************************/ + public Map getServiceTypes() + throws MobyException { + String result = getServiceTypesAsXML(); + Map results = new TreeMap (getStringComparator()); + MobyServiceType[] types = createServiceTypesFromXML (result); + for (int i = 0; i < types.length; i++) { + results.put (types[i].getName(), + types[i].getDescription()); + } + return results; + } + + // + protected String getServiceTypesAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceTypes", + new Object[] {}); + } + + // but be aware that the created MobyServiceTypes are not complete + // - they do not have the relationship information; that's why + // this method is not public; the full service types are available + // from CentralDigest implementations + protected MobyServiceType[] createServiceTypesFromXML (String result) + throws MobyException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceType"); + if (list == null || list.getLength() == 0) + return new MobyServiceType[] {}; + MobyServiceType[] results = new MobyServiceType [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); + st.setLSID (elem.getAttribute ("lsid")); + st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = st; + } + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     *  <Namespaces>
+     *     <Namespace name="namespace" lsid="...">
+     *            <Description><![CDATA[free text description here]]></Description>
+     *            <contactEmail>...</contactEmail>
+     *            <authURI>...</authURI>
+     *     </Namespace>
+     *          ...
+     *          ...
+     *  </Namespaces>
+     * 
+ *************************************************************************/ + public MobyNamespace[] getFullNamespaces() + throws MobyException { + + String result = getNamespacesAsXML(); + return createNamespacesFromXML (result); + } + + // + protected String getNamespacesAsXML() + throws MobyException { + return (String)doCall ("retrieveNamespaces", + new Object[] {}); + } + + // + protected MobyNamespace[] createNamespacesFromXML (String result) + throws MobyException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); + if (list == null || list.getLength() == 0) { + return new MobyNamespace[] {}; + } + MobyNamespace[] results = new MobyNamespace [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); + nm.setLSID (elem.getAttribute ("lsid")); + nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = nm; + } + + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * + * @deprecated Replaced by {@link #getFullNamespaces} that gives + * more information for the same price.

+ *************************************************************************/ + public Map getNamespaces() + throws MobyException { + + Map results = new TreeMap (getStringComparator()); + MobyNamespace[] namespaces = getFullNamespaces(); + for (int i = 0; i < namespaces.length; i++) { + results.put (namespaces[i].getName(), + namespaces[i].getDescription()); + } + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *

+     *  <objectNames>
+     *     <Object name="objectName" lsid="...">
+     *            <Description><![CDATA[free text description here]]></Description>
+     *     </Object>
+     *          ...
+     *          ...
+     *  </objectNames>
+     * 
+ *************************************************************************/ + public Map getDataTypeNames() + throws MobyException { + String result = getDataTypeNamesAsXML(); + return createDataTypeNamesFromXML (result, true); + } + + // + protected String getDataTypeNamesAsXML() + throws MobyException { + return (String)doCall ("retrieveObjectNames", + new Object[] {}); + } + + // if onlyNames == true + // Map: data type name -> description (String) + // else + // Map: data type name -> MobyDataType[] + // (filled with name, description, and lsid) + protected Map createDataTypeNamesFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Object"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + if (name == null) + continue; // ignore no-named data types + String desc = ""; + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("Description")) { + desc = getFirstValue (children.item (j)); + break; + } + } + if (onlyNames) { + results.put (name, desc); + } else { + MobyDataType dt = new MobyDataType (name); + dt.setDescription (desc); + dt.setLSID (elem.getAttribute ("lsid")); + results.put (name, dt); + } + } + return results; + } + + + /************************************************************************** + * Parses and imports the following XML. An example: + * + *
+     * <retrieveObjectDefinition>
+     *   <objectType lsid="...">go_term</objectType>
+     *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
+     *   <authURI>http://www.illuminae.com</authURI>
+     *   <contactEmail>markw at illuminae.com</contactEmail>
+     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
+     *      <objectType articleName=''>urn:lsid:biomoby.org:objectclass:object</objectType>
+     *   </Relationship>
+     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
+     *      <objectType articleName='Term'>urn:lsid:biomoby.org:objectclass:string</objectType>
+     *      <objectType articleName='Definition'>urn:lsid:biomoby.org:objectclass:string</objectType>
+     *   </Relationship>
+     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:has'>
+     *      <objectType articleName='Problems'>urn:lsid:biomoby.org:objectclass:string</objectType>
+     *      <objectType articleName='Issues'>urn:lsid:biomoby.org:objectclass:string</objectType>
+     *   </Relationship>
+     * </retrieveObjectDefinition>
+     * 
+ *************************************************************************/ + public MobyDataType getDataType (String dataTypeName) + throws MobyException, NoSuccessException { + + String result = getDataTypeAsXML (dataTypeName); + return createDataTypeFromXML (result, dataTypeName); + } + + public MobyDataType[] getDataTypes() + throws MobyException, NoSuccessException { + Map datatypeMap = getDataTypeNames(); + MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; + int i = 0; + for(String dataTypeName: datatypeMap.keySet()){ + datatypes[i++] = getDataType(dataTypeName); + } + return datatypes; + } + + protected String getDataTypeAsXML (String dataTypeName) + throws MobyException, NoSuccessException { + + return (String)doCall ("retrieveObjectDefinition", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + }); + } + + protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) + throws MobyException, NoSuccessException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); + NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); + if (list == null || list.getLength() == 0) + throw new NoSuccessException ("Data Type name was not found.", + dataTypeName); + MobyDataType data = null; + Element elem = (Element)list.item (0); + NodeList children = elem.getChildNodes(); + + // first find the "real" (LSID-ized) data type name + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("objectType")) { + data = new MobyDataType (getFirstValue (children.item (j))); + data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); + break; + } + } + + // if not found (unprobable) use the name given by the caller + if (data == null) + data = new MobyDataType (dataTypeName); + + // now fill the data type object with the rest of attributes + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + data.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("authURI")) { + data.setAuthority (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + data.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Relationship")) { + String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); + if (relationshipType.endsWith ("isa")) { + + NodeList parents = children.item (j).getChildNodes(); + for (int k = 0; k < parents.getLength(); k++) { + if (parents.item (k).getNodeName().equals ("objectType")) { + data.addParentName (getFirstValue (parents.item (k))); + } + } + } else if (relationshipType.endsWith ("hasa")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + getFirstValue (belows.item (k)), + Central.iHASA ); + } + } + } else if (relationshipType.endsWith ("has")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + belows.item (k).getFirstChild().getNodeValue(), + Central.iHAS ); + } + } + } + } + } + return data; + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName) + throws MobyException, NoSuccessException { + + Map names = getServiceNames(); + + for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + if ( ((String)entry.getKey()).equals (serviceName) ) + return getServiceWSDL (serviceName, (String)entry.getValue()); + } + + throw new NoSuccessException ("Service not found.", serviceName); + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName, String authority) + throws MobyException, NoSuccessException { + + String cacheId = "getServiceWSDL" + serviceName + ":" + authority; + String cachedResults = (String)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("retrieveService", + new Object[] { + "" + + "" + + "" + }); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + Element service = document.getDocumentElement(); + Node wsdl = service.getFirstChild(); + if (wsdl == null) + throw new NoSuccessException ("Service not found OR WSDL is not available.", + serviceName + " (" + authority + ")"); + + String results = wsdl.getNodeValue(); + setContents (cacheId, results); + return results; + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterDataTypeXML (MobyDataType dataType) { + + // build the ISA tag (expressing hierarchy of data types) + String[] names = dataType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + // build the HASA/HAS tags (expressing containments of data types) + MobyRelationship[] children = dataType.getChildren(); + StringBuffer buf2 = new StringBuffer(); // for HASA + StringBuffer buf3 = new StringBuffer(); // for HAS + for (int i = 0; i < children.length; i++) { + if (children[i].getRelationshipType() == Central.iHASA) { + buf2.append (""); + buf2.append (children[i].getDataTypeName()); + buf2.append (""); + } else if (children[i].getRelationshipType() == Central.iHAS) { + buf3.append (""); + buf3.append (children[i].getDataTypeName()); + buf3.append (""); + } + } + + return + "" + + "" + dataType.getName() + "" + + "" + + "" + + "" + new String (buf) + + "" + + "" + new String (buf2) + + "" + + "" + new String (buf3) + + "" + + "" + dataType.getAuthority() + "" + + "" + dataType.getEmailContact() + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerObjectClass", + new Object[] { getRegisterDataTypeXML (dataType) }); + dataType.setId (checkRegistration (result, dataType)[0]); + } + + /************************************************************************* + * B + *************************************************************************/ + public void unregisterDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterObjectClass", + new Object[] { + "" + + "" + dataType.getName() + "" + + "" + }); + checkRegistration (result, dataType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceTypeXML (MobyServiceType serviceType) { + + // build the ISA tag (expressing hierarchy of service types) + String[] names = serviceType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + return + "" + + "" + serviceType.getName() + "" + + "" + serviceType.getEmailContact() + "" + + "" + serviceType.getAuthority() + "" + + "" + + "" + + "" + new String (buf) + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerServiceType", + new Object[] { getRegisterServiceTypeXML (serviceType) }); + serviceType.setId (checkRegistration (result, serviceType)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterServiceType", + new Object[] { + "" + + "" + serviceType.getName() + "" + + "" + }); + checkRegistration (result, serviceType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterNamespaceXML (MobyNamespace namespace) { + return + "" + + "" + namespace.getName() + "" + + "" + namespace.getEmailContact() + "" + + "" + namespace.getAuthority() + "" + + "" + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("registerNamespace", + new Object[] { getRegisterNamespaceXML (namespace) }); + namespace.setId (checkRegistration (result, namespace)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterNamespace", + new Object[] { + "" + + "" + namespace.getName() + "" + + "" + }); + checkRegistration (result, namespace); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceXML (MobyService service) { + return + "" + + "" + service.getCategory() + "" + + "" + service.getName() + "" + + "" + service.getType() + "" + + "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + + "" + service.getAuthority() + "" + + "" + escapeXML (service.getSignatureURL()) + "" + + "" + escapeXML (service.getURL()) + "" + + "" + service.getEmailContact() + "" + + "" + (service.isAuthoritative() ? "1" : "0") + "" + + "" + + "" + + buildPrimaryInputTag (service) + + buildSecondaryInputTag (service) + + buildOutputTag (service) + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerService", + new Object[] { getRegisterServiceXML (service) }); + String[] registered = checkRegistration (result, service); + service.setId (registered [0]); + service.setRDF (registered [1]); + String pathToRDF = service.getPathToRDF(); + if ( ! pathToRDF.equals ("") ) { + File fileRDF = new File (pathToRDF); + try { + PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); + fileout.println (registered [1]); + fileout.close(); + } catch (IOException e) { + StringBuffer buf = new StringBuffer (100); + buf.append ("Failed to save RDF in '"); + buf.append (fileRDF.getAbsolutePath() + "'. "); + buf.append (e.toString()); + try { + File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); + PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); + fileout.println (registered [1]); + fileout.close(); + buf.append ("\nReturned RDF file was therefore stored in: "); + buf.append (tmpFile.getAbsolutePath()); + } catch (IOException e2) { + buf.append ("\nEven saving in a temporary file failed: "); + buf.append (e2.toString()); + } + throw new MobyException (buf.toString()); + } + } + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterService", + new Object[] { + "" + + "" + service.getAuthority() + "" + + "" + service.getName() + "" + + "" + }); + checkRegistration (result, service); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String serviceType) + throws MobyException { + if (serviceType == null) + return new MobyService[] {}; + MobyService pattern = new MobyService ("dummy"); + pattern.setCategory (""); + pattern.setType (serviceType); + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String[] keywords) + throws MobyException { + if (keywords == null) + return new MobyService[] {}; + return findService (null, keywords); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern) + throws MobyException { + if (pattern == null) + return new MobyService[] {}; + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords) + throws MobyException { + return findService (pattern, keywords, true, true); + } + + /************************************************************************** + * All 'findService' methods end up here. + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + if (pattern == null) { + pattern = new MobyService ("dummy"); + pattern.setCategory (""); + } + + String result = + getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); + MobyService[] services = extractServices (result); + return services; + } + + // ...actually all 'findService' methods end up here + protected String getServicesAsXML (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + String[] query = new String[] { + "" + + buildQueryObject (pattern, keywords, + includeParentDataTypes, + includeChildrenServiceTypes, + false) + + "" + }; + return (String)doCall ("findService", query); + } + + /************************************************************************** + * + *************************************************************************/ + public String call (String methodName, String inputXML) + throws MobyException { + Object result; + if (inputXML == null || inputXML.equals ("")) + result = doCall (methodName, new Object[] { }); + else + result = doCall (methodName, new Object[] { inputXML }); + return (String)result; + } + + /************************************************************************** + * + *************************************************************************/ + protected static String resultToString (Object result) + throws MobyException { + if (result == null) + throw new MobyException ("Returned result is null."); + if (result instanceof String) + return (String)result; + if (result instanceof String[]) { + String[] tmp = (String[])result; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < tmp.length; i++) + buf.append (tmp[i]); + return new String (buf); + } + if (result instanceof byte[]) + return new String ((byte[])result); + + throw new MobyException ("Unknown type of result: " + result.getClass().getName()); + } + + /************************************************************************** + * + *************************************************************************/ + public boolean setDebug (boolean enabled) { + boolean oldMode = debug; + debug = enabled; + return oldMode; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     * <Relationships>
+     *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
+     *     <serviceType>urn:lsid:biomoby.org:servicetype:analysis</serviceType>
+     *     <serviceType>urn:lsid:biomoby.org:servicetype:service</serviceType>
+     *   </Relationship>
+     * </Relationships>
+     * 
+ *************************************************************************/ + public String[] getServiceTypeRelationships (String serviceTypeName, + boolean expand) + throws MobyException { + String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); + return createServiceTypeRelationshipsFromXML (result); + } + + // + protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, + boolean expand) + throws MobyException { + return + (String)doCall ("Relationships", + new Object[] { + "" + + "" + serviceTypeName + "" + + "" + Central.ISA + "" + + "" + (expand ? "1" : "0") + "" + + "" + }); + } + + // + protected String[] createServiceTypeRelationshipsFromXML (String result) + throws MobyException { + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("serviceType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + } + String[] results = new String [v.size()]; + v.copyInto (results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     *<Relationships>
+     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
+     *  </Relationship>
+     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
+     *  </Relationship>
+     *</Relationships>
+     * 
+ * + * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an + * attributes 'lsid' and 'articleName' in <objectType> element. + *************************************************************************/ + public Map getDataTypeRelationships (String dataTypeName) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName; + Map cachedResults = (Map)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + Central.ISA + "" + + "" + Central.HASA + "" + + "" + Central.HAS + "" + + "1" + + "" + }); + + // parse returned XML + Map results = new HashMap(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String relType = elem.getAttribute ("relationshipType"); + NodeList children = elem.getChildNodes(); + Vector v = new Vector(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + String[] names = new String [v.size()]; + v.copyInto (names); + results.put (relType, names); + } + + setContents (cacheId, results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     *<Relationships>
+     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
+     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
+     *  </Relationship>
+     *</Relationships>
+     * 
+ *************************************************************************/ + public String[] getDataTypeRelationships (String dataTypeName, + String relationshipType) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + relationshipType + "" + + "1" + + "" + }); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + // it should always be just one element in this list + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + } + String[] results = new String [v.size()]; + v.copyInto (results); + + setContents (cacheId, results); + return results; + } + +// /************************************************************************** +// * +// *************************************************************************/ +// public MobyRelationship[] getRelationships (String dataTypeName) +// throws MobyException { +// return null; +// } + + + /************************************************************************** + * + *************************************************************************/ + public String getRegistryEndpoint() { + return endpoint.toString(); + } + + /************************************************************************** + * + *************************************************************************/ + public String getRegistryNamespace() { + return uri; + } + + /************************************************************************** + * Parses and imports the following XML. + *
+     * <resourceURLs>
+     *   <Resource name="Service"         url="..." />
+     *   <Resource name="Object"          url="..." />
+     *   <Resource name="Namespace"       url="..." />
+     *   <Resource name="ServiceInstance" url="..." />
+     *   <Resource name="Full"            url="..." />
+     * </resourceURLs>
+     * 
+ *************************************************************************/ + public MobyResourceRef[] getResourceRefs() + throws MobyException { + + String cacheId = "retrieveResourceURLs"; + MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveResourceURLs", + new Object[] {}); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Resource"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + try { + v.addElement + (new MobyResourceRef (elem.getAttribute ("name"), + new URL ((String)elem.getAttribute ("url")), + elem.getAttribute ("type"))); + } catch (MalformedURLException e2) { + if (debug) + System.err.println ("Bad URL: " + elem.getAttribute ("url")); + } + } + + MobyResourceRef[] results = new MobyResourceRef [v.size()]; + v.copyInto (results); + + // Add this data to the cache in case we get called again + setContents (cacheId, results); + + return results; + } + + /************************************************************************** + * + *************************************************************************/ + public InputStream getResource (String resourceName) + throws MobyException { + + MobyResourceRef[] resourceRefs = getResourceRefs(); + for (int i = 0; i < resourceRefs.length; i++) { + if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { + return Utils.getInputStream (resourceRefs[i].getResourceLocation()); + } + } + throw new MobyException ("No resource found for '" + resourceName + "'."); + } + + /************************************************************************** + * Return a case-insensitive comparator of Strings. It is used to + * create various TreeMaps where keys are strings. + *************************************************************************/ + protected static Comparator getStringComparator() { + return new Comparator() { + public int compare (Object o1, Object o2) { + return ((String)o1).compareToIgnoreCase ((String)o2); + } + }; + } + + // cache URL/URI so we only check once + private static String CHECKED_URL = null; + private static String CHECKED_URI = null; + + /** + * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared + * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods + * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. + * + * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism + */ + public static CentralImpl getDefaultCentral() throws MobyException{ + return getDefaultCentral(null); + } + + public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ + if(reg == null && defaultCentrals.containsKey("")){ + return defaultCentrals.get(""); + } + else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ + return defaultCentrals.get(reg.getEndpoint()); + } + + String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); + if(resURL != null){ + System.err.println("Loading "+resURL); + try{ + LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); + for(String line = reader.readLine(); line != null; line = reader.readLine()){ + if(!line.trim().startsWith("#")){ + className = line.trim(); + break; + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Error reading " + resURL, + e); + } + } + try{ + System.err.println("Central class is "+className); + Class clazz = Class.forName(className); + if(reg == null){ // should use default nullary c-tor + defaultCentrals.put("", (CentralImpl) clazz.newInstance()); + } + else{ // should have (String endpoint, String namespace) c-tor + for(Constructor ctor: clazz.getDeclaredConstructors()){ + Class[] params = ctor.getParameterTypes(); + if(params.length == 2 && params[0].getName().equals("java.lang.String") && + params[1].getName().equals("java.lang.String") ){ + defaultCentrals.put(reg.getEndpoint(), + (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); + break; + } + } + if(!defaultCentrals.containsKey(reg.getEndpoint())){ + logger.log(Level.WARNING, + "Could not find required (String endpoint, String namespace)" + + "constructor for class " + className); + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Could not load class " + className, + e); + if(reg == null){ + defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. + } + else{ + defaultCentrals.put(reg.getEndpoint(), + new CentralImpl(reg.getEndpoint(), reg.getNamespace())); + } + } + + return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); + } + + /** + * + * @return a String representing the Default mobycentral endpoint. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central endpoint is returned, otherwise DEFAULT_ENDPOINT + * is returned. + */ + public static String getDefaultURL() { + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + + if (check) { + // return the last checked url if we have done this before + if (CHECKED_URL != null && CHECKED_URL.trim() != "") { + return CHECKED_URL; + } + + // create a HttpClient object + HttpClient client = new HttpClient(); + // set up the Head method + HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); + // do not follow redirects or we will get a 411 error + method.setFollowRedirects(false); + // retry 3 times + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); + // set the user agent ... should probably make this something more reasonable + method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); + try { + // Execute the method. + int statusCode = client.executeMethod(method); + + if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { + System.err.println("Method failed: " + + method.getStatusLine()); + } else { + try { + String location = method.getResponseHeader("location").getValue(); + CHECKED_URL = location; + try { + CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; + } catch (MalformedURLException murle ) { + CHECKED_URI = DEFAULT_NAMESPACE; + } + return CHECKED_URL; + } catch (NullPointerException npe) { + return DEFAULT_ENDPOINT; + } + } + } catch (HttpException e) { + System.err.println("Fatal protocol violation: " + + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + System.err.println("Fatal transport error: " + e.getMessage()); + e.printStackTrace(); + } finally { + // Release the connection. + method.releaseConnection(); + } + + } else { + return DEFAULT_ENDPOINT; + } + return DEFAULT_ENDPOINT; + } + + /** + * + * @return a String representing the default mobycentral uri. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central namespace is returned, otherwise DEFAULT_NAMESPACE + * is returned. + */ + public static String getDefaultURI() { + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + if (check) { + if (CHECKED_URI != null && CHECKED_URI.trim() != "") { + return CHECKED_URI; + } + // need to check ... + getDefaultURL(); + return CHECKED_URI; + } else { + return DEFAULT_NAMESPACE; + } + } + /************************************************************************** + * Convert non-suitable characters in a XML string into their + * entity references.

+ * + * Adapted from jDom. + * + * @param str input to be converted + * @return If there were any non-suitable characters, return a new + * string with those characters escaped, otherwise return the + * unmodified input string + * + *************************************************************************/ + public String escapeXML (String str) { + StringBuffer buffer = null; + char ch; + String entity; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt (i); + switch (ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; + case '&' : + entity = "&"; + break; + default : + entity = null; + break; + } + if (buffer == null) { + if (entity != null) { + // An entity occurred, so we'll have to use StringBuffer + // (allocate room for it plus a few more entities). + buffer = new StringBuffer (str.length() + 20); + // Copy previous skipped characters and fall through + // to pickup current character + buffer.append (str.substring (0, i)); + buffer.append (entity); + } + } else { + if (entity == null) { + buffer.append (ch); + } else { + buffer.append (entity); + } + } + } + + // If there were any entities, return the escaped characters + // that we put in the StringBuffer. Otherwise, just return + // the unmodified input string. + return (buffer == null) ? str : buffer.toString(); + } + + /************************************************************************* + * Format an exception. + *************************************************************************/ + public static String formatFault (AxisFault e, String endpoint, QName method) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + formatFault (e, new PrintStream (baos), endpoint, method); + return baos.toString(); + } + + /************************************************************************* + * Format an exception. + *************************************************************************/ + public static void formatFault (AxisFault e, PrintStream out, + String endpoint, QName method) { + + out.println ("===ERROR==="); + out.println ("Fault details:"); + // for some obvious errors I do not print all details (with a lenghty trace stack) + String faultString = e.getFaultString(); + if ( (! faultString.startsWith ("java.net.ConnectException")) && + (faultString.indexOf ("Could not find class for the service named:") == -1) + ) { + org.w3c.dom.Element[] details = e.getFaultDetails(); + for (int i = 0; i < details.length; i++) { + String s = details[i].toString().replaceAll ("<", "<"); + s = s.replaceAll (">", ">"); + out.println (s); + } + } + out.println ("Fault string: " + faultString); + out.println ("Fault code: " + e.getFaultCode()); + out.println ("Fault actor: " + e.getFaultActor()); + if (endpoint != null || method != null) + out.println ("When calling:"); + if (endpoint != null) + out.println ("\t" + endpoint); + if (method != null) + out.println ("\t" + method); + out.println ("==========="); + } + + +} From groscurt at dev.open-bio.org Wed Dec 3 10:21:13 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 10:21:13 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031521.mB3FLDqF013719@dev.open-bio.org> groscurt Wed Dec 3 10:21:13 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard In directory dev.open-bio.org:/tmp/cvs-serv13676/src/main/org/biomoby/service/dashboard Modified Files: SimpleClientPanel.java ServiceCallerModel.java DashboardProperties.java Log Message: changes made for the authentication... without formatting this time moby-live/Java/src/main/org/biomoby/service/dashboard SimpleClientPanel.java,1.13,1.14 ServiceCallerModel.java,1.7,1.8 DashboardProperties.java,1.30,1.31 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java 2008/11/26 08:54:21 1.13 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java 2008/12/03 15:21:12 1.14 @@ -1,791 +1,838 @@ -// SimpleClientPanel.java -// -// Created: December 2005 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.service.dashboard; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.util.Date; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.ButtonGroup; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JRadioButton; -import javax.swing.JSplitPane; -import javax.swing.JTextField; -import javax.swing.tree.DefaultMutableTreeNode; - -import org.biomoby.service.dashboard.data.DataContainer; -import org.biomoby.service.dashboard.data.ServiceInputPanel; -import org.biomoby.shared.MobyDataType; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.tulsoft.shared.UUtils; -import org.tulsoft.tools.gui.AwtUtils; -import org.tulsoft.tools.gui.JFileChooserWithHistory; -import org.tulsoft.tools.gui.JTextFieldWithHistory; -import org.tulsoft.tools.gui.SwingUtils; - -/** - * A panel allowing to formulate input data and to call an arbitrary Biomoby service. Its interface is however not that - * user-friendly, and it is supposed to be used more or less for testing purposes in time when a new service is being - * created and developed. - *

- * - * @author Martin Senger - * @version $Id$ - */ - -public class SimpleClientPanel extends AbstractPanel { - - private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory - .getLog( SimpleClientPanel.class ); - - /** - * A property name. Its value contains a name of color that will be used to display service name. - */ - protected static final String P_S_TITLE_COLOR = "simpleclient.service.title.color"; - - /** - * A property name. Its value contains a name of color that will be used as background for editable console with XML - * input. - */ - protected static final String P_S_EDIT_BGCOLOR = "simpleclient.service.edit.bgcolor"; - - // some texts - protected static final String INIT_SELECT = "

Start by selecting a service
" - + "that you wish to call.
"; - - protected static final String CALLER_ERROR = "Sorry, an error happened when calling a service.\n\n"; - - protected static final Insets BREATH_UP = new Insets( 6, 6, 0, 6 ); - protected static final Insets BREATH_DOWN = new Insets( 0, 6, 6, 6 ); - - // associated models working behind the scene - RegistryModel registryModel; - ServiceCallerModel callerModel; - - // components that are used from more methods - JLabel selService; - CommonConsole input; - JFileChooserWithHistory outFile, inFile; - JButton runButton, stopButton; - JCheckBox iShowXML, iFromFile; - JTextFieldWithHistory className, endpoint; - JPanel dataTablesPanel; - ServiceInputPanel inputDataTables; - MySwingWorker runWorker; - ResultsPanel results; - JComponent resultsComp; - JSplitPane resSplit; - // JTextFieldWithHistory recentServices; - - boolean selectionAllowed = false; - - // shared icons - protected static Icon runIcon, runIconDis; - protected static Icon stopIcon, stopIconDis; - protected static Icon addDataIcon, addDataIconDis; - - /******************************************************************************************************************* - * Default constructor. - ******************************************************************************************************************/ - public SimpleClientPanel() { - super(); - panelIconFileName = "images/debug.gif"; - } - - /******************************************************************************************************************* - * Load shared icons. - ******************************************************************************************************************/ - protected void loadIcons() { - super.loadIcons(); - - if ( runIcon == null ) runIcon = loadIcon( "images/smallRun.gif" ); - if ( runIconDis == null ) runIconDis = loadIcon( "images/smallRun_dis.gif" ); - - if ( stopIcon == null ) stopIcon = loadIcon( "images/smallCancel.gif" ); - if ( stopIconDis == null ) stopIconDis = loadIcon( "images/smallCancel_dis.gif" ); - - if ( addDataIcon == null ) addDataIcon = loadIcon( "images/smallAnnotate.gif" ); - if ( addDataIconDis == null ) addDataIconDis = loadIcon( "images/smallAnnonate_dis.gif" ); - - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public JComponent getComponent( PropertyChannel aPropertyChannel ) { - setPropertyChannel( aPropertyChannel ); - registryModel = createRegistryModel(); - callerModel = new ServiceCallerModel(); - callerModel.setPropertyChannel( aPropertyChannel ); - - if ( pComponent != null ) return pComponent; - pComponent = new JPanel( new GridBagLayout(), true ); - - // result panel - results = new ResultsPanel(); - resultsComp = results.getComponent( aPropertyChannel ); - propertyChannel.addPropertyChangeListener( new PropertyChangeListener() { - public void propertyChange( PropertyChangeEvent e ) { - if ( DP_DETACH_VIEW.equals( e.getPropertyName() ) ) { - - MobyService srv = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - String title = ( srv == null ? "Service results" : srv.getName() + " at " + new Date() ); - JComponent current = results.getComponent( propertyChannel ); - results.adjustForDetachement(); - JFrame newFrame = SwingUtils.createSoftMainFrame( current, title ); - Dimension dim = current.getPreferredSize(); - SwingUtils.showMainFrameRelativeTo( pComponent, newFrame, ( int ) dim.getWidth(), ( int ) dim - .getHeight() ); - results = new ResultsPanel(); - resultsComp = results.getComponent( propertyChannel ); - resSplit.setBottomComponent( resultsComp ); - } - } - } ); - - // panel with all the fields (except for building inputs) - JPanel controls = getControlPanel(); - - // panel with input data - JPanel inputData = getInputPanel(); - updateInputDataPanel( INIT_SELECT ); - - // service ontology tree - JPanel sBoard = new JPanel( new GridBagLayout() ); - // JLabel lRecent = new JLabel ("Recently called services"); - // recentServices = createText (null, - // DP_SC_SERVICES, - // DP_SC_SERVICES); - // recentServices.addActionListener (new ActionListener() { - // public void actionPerformed (ActionEvent e) { - // String contents = ((JTextFieldWithHistory)e.getSource()).getText(); - // if (! "".equals (contents) && selectionAllowed) { - // System.out.println ("SEL: " + contents); - // selectService (contents); - // } - // } - // }); - - ServicesBoard servicesBoard = new ServicesBoard( registryModel, null, propertyChannel, new CustomServicesTree( - registryModel, null ) ); - log.debug( "Services tree update started" ); - servicesBoard.updateTree( CommonTree.SORTED_BY_AUTHORITY ); - // SwingUtils.addComponent (sBoard, lRecent, 0, 0, 1, 1, NONE, NWEST, 0.0, 0.0, BREATH_UP); - // SwingUtils.addComponent (sBoard, recentServices, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0, BREATH_DOWN); - SwingUtils.addComponent( sBoard, servicesBoard, 0, 2, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - - // split it into moving panels - JSplitPane split = hSplit( resSplit = vSplit( hSplit( controls, sBoard, 0.5 ), resultsComp, 0.1 ), inputData, - 0.5 ); - - SwingUtils.addComponent( pComponent, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - - // initialize by a last used service name from preferences - String lastServiceName = getPrefValue( DP_SC_SERVICE_NAME, "" ); - if ( !"".equals( lastServiceName ) ) selectService( lastServiceName ); - - return pComponent; - } - - /******************************************************************************************************************* - * Create a sub-panel for all the controls... - ******************************************************************************************************************/ - protected JPanel getControlPanel() { - JPanel p = new JPanel( new GridBagLayout() ); - - // (selected) service name - selService = new JLabel(); - selService.setFont( FAT_BORDER_FONT ); - selService.setForeground( GraphColours.getColour( DashboardConfig.getString( P_S_TITLE_COLOR, null ), - Color.blue ) ); - - // how to invoke the service - JPanel howTo = createTitledPanel( "Service invocation" ); - endpoint = createText( null, DP_ENDPOINT, DP_ENDPOINT ); - className = createText( null, DP_IMPL_CLASS, DP_IMPL_CLASS ); - - ButtonGroup group = new ButtonGroup(); - JRadioButton htNone, htRegistry, htEndpoint, htLocal, htNewURL; - group.add( htEndpoint = createHowToButton( "Use service's usual endpoint", DP_CS_URL ) ); - htNone = createHowToButton( "No real call, just show/echo input", DP_CS_NONE ); - htNone.addItemListener( new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - if ( enabled ) - runButton.setText( " Show Input " ); - else { - if ( propertyChannel.getBoolean( DP_INP_PING, false ) ) { - runButton.setText( " Ping Service " ); - } - else { - runButton.setText( " Call Service " ); - } - } - } - } ); - group.add( htNone ); - group.add( htRegistry = createHowToButton( "Ask registry where service is, and call it", DP_CS_REGISTRY ) ); - group.add( htNewURL = createHowToButton( "Use this endpoint", DP_CS_NEWURL ) ); - group.add( htLocal = createHowToButton( "Use this local class", DP_CS_CLASS ) ); - - // run the service - // determine button text from preferences - boolean usingPing = getPrefValue( DP_INP_PING, false ); - boolean usingAsBytes = getPrefValue( DP_INP_ASBYTES, false ); - String runLabel = " Call Service "; - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runLabel = " Show Input "; - else if ( usingPing ) runLabel = " Ping Service "; - - runButton = createButton( runLabel, "Invoke selected service", KeyEvent.VK_C, new ActionListener() { - public void actionPerformed( ActionEvent e ) { - MobyService srv = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - if ( srv != null ) { - // if the authentication was selected a dialog opens to ask for the user/password - if ( propertyChannel.getBoolean( DP_AUTHENTICATION, false ) ) { - askForAuthentication(); - } - // if not make sure to remove any previous authentication - else { - propertyChannel.remove( DP_USER_AUTHENTICATION ); - propertyChannel.remove( DP_PASSWORD_AUTHENTICATION ); - } - runWorker = new MySwingWorker( srv ); - runWorker.start(); - } - } - } ); - runButton.setIcon( runIcon ); - runButton.setDisabledIcon( runIconDis ); - runButton.setEnabled( false ); // will enable when a service is selected - - stopButton = createButton( " Stop service ", "Cancel connection to a running service", KeyEvent.VK_S, - new ActionListener() { - public void actionPerformed( ActionEvent e ) { - if ( runWorker != null ) { - // runWorker.interrupt(); // no sense with the current Biomoby API - runWorker.cancel(); - } - serviceFinished(); - } - } ); - stopButton.setIcon( stopIcon ); - stopButton.setDisabledIcon( stopIconDis ); - stopButton.setEnabled( false ); // will enable when a service is called - - JPanel buttonPanel = createButtonPanel( new JButton[] { runButton, stopButton } ); - - JCheckBox asPing = createCheckBox( "'Ping' this service", usingPing, -1, new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPropertySelect( enabled, DP_INP_PING ); - setPrefValue( DP_INP_PING, enabled ); - propertyChannel.put( DP_INP_PING, new Boolean( enabled ).toString() ); - if ( enabled ) { - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runButton.setText( " Show Input " ); - else - runButton.setText( " Ping Service " ); - } - else { - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runButton.setText( " Show Input " ); - else - runButton.setText( " Call Service " ); - } - } - } ); - setPropertySelect( usingPing, DP_INP_PING ); - asPing.setToolTipText( "A Moby 'Ping' is used to determine if the service is responsive " - + "and if it responds in an API-compliant manner." ); - Font font = asPing.getFont(); - asPing.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - JCheckBox asBytes = createCheckBox( "Send data to service as a byte array", usingAsBytes, -1, - new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPropertySelect( enabled, DP_INP_ASBYTES ); - setPrefValue( DP_INP_ASBYTES, enabled ); - propertyChannel.put( DP_INP_ASBYTES, new Boolean( enabled ).toString() ); - } - } ); - setPropertySelect( usingAsBytes, DP_INP_ASBYTES ); - asBytes.setToolTipText( "It should not have any effect on result; it is for debugging" ); - font = asBytes.getFont(); - asBytes.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - JCheckBox authenticationBox = createCheckBox( "Use a user/password for authentication", false, -1, - new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - propertyChannel.put( DP_AUTHENTICATION, e.getStateChange() == ItemEvent.SELECTED ); - } - } ); - authenticationBox.setToolTipText( "If the service requires authentication. " - + "A dialog will open if you call the service to enter the authentication." ); - font = authenticationBox.getFont(); - authenticationBox.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - SwingUtils.addComponent( howTo, htEndpoint, 0, 0, 2, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htNewURL, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, endpoint, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htRegistry, 0, 2, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, htLocal, 0, 3, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, className, 1, 3, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htNone, 0, 4, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, asPing, 0, 5, 2, 1, NONE, NWEST, 0.0, 0.0, BREATH_TOP ); - SwingUtils.addComponent( howTo, asBytes, 0, 6, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, authenticationBox, 0, 7, 2, 1, NONE, NWEST, 0.0, 0.0 ); - - Component glue = Box.createVerticalGlue(); - SwingUtils.addComponent( p, selService, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0 ); - SwingUtils.addComponent( p, howTo, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( p, buttonPanel, 0, 2, 1, 1, NONE, CENTER, 0.0, 0.0, BREATH_TOP ); - SwingUtils.addComponent( p, glue, 0, 3, 1, 1, VERT, NWEST, 0.0, 1.0 ); - return p; - } - - /******************************************************************************************************************* - * Select/unselect using 'send as bytes' or 'ping'... - ******************************************************************************************************************/ - protected void setPropertySelect( boolean enabled, String property ) { - setPrefValue( property, enabled ); - propertyChannel.put( property, new Boolean( enabled ).toString() ); - } - - /******************************************************************************************************************* - * Opens a dialog and asks for webservice authentication - ******************************************************************************************************************/ - private void askForAuthentication() { - final JDialog dialog = new JDialog( new JFrame(), "Authentication", true ); - JPanel panel = new JPanel( new GridBagLayout() ); - panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); - - Insets insets = new Insets( 4, 4, 4, 4 ); - - JLabel label = new JLabel( "Please enter your username and password !" ); - SwingUtils.addComponent( panel, label, 0, 0, 2, 1, HORI, CENTER, 1, 0, insets ); - - label = new JLabel( "User: " ); - SwingUtils.addComponent( panel, label, 0, 1, 1, 1, HORI, NWEST, 0, 0, insets ); - - final JTextField userField = new JTextField( propertyChannel.getString( DP_USER_AUTHENTICATION ), 20 ); - SwingUtils.addComponent( panel, userField, 1, 1, 1, 1, HORI, NWEST, 0, 0, insets ); - - label = new JLabel( "Password: " ); - SwingUtils.addComponent( panel, label, 0, 2, 1, 1, HORI, NWEST, 0, 0, insets ); - - final JPasswordField passwordField = new JPasswordField( - propertyChannel.getString( DP_PASSWORD_AUTHENTICATION ), 20 ); - SwingUtils.addComponent( panel, passwordField, 1, 2, 1, 1, HORI, NWEST, 0, 0, insets ); - - JButton button = new JButton( "Enter..." ); - button.addActionListener( new ActionListener() { - public void actionPerformed( ActionEvent e ) { - propertyChannel.put( DP_USER_AUTHENTICATION, userField.getText() ); - propertyChannel.put( DP_PASSWORD_AUTHENTICATION, passwordField.getPassword() ); - - dialog.setVisible( false ); - } - } ); - SwingUtils.addComponent( panel, button, 0, 3, 2, 1, HORI, CENTER, 0, 0, insets ); - - dialog.setContentPane( panel ); - dialog.pack(); - dialog.setLocationRelativeTo( this ); - dialog.setVisible( true ); - } - - /******************************************************************************************************************* - * Create a specialized radio button - for various ways how to call a service. - ******************************************************************************************************************/ - private JRadioButton createHowToButton( String title, String howTo ) { - JRadioButton radio = new JRadioButton( title ); - radio.setActionCommand( howTo ); - radio.addActionListener( howToListener ); - String initHowTo = getPrefValue( DP_CALL_SERVICE, DP_CS_NONE ); - if ( howTo.equals( initHowTo ) ) { - radio.setSelected( true ); - radio.setEnabled( true ); - propertyChannel.put( DP_CALL_SERVICE, howTo ); - } - endpoint.setEnabled( initHowTo.equals( DP_CS_NEWURL ) ); - className.setEnabled( initHowTo.equals( DP_CS_CLASS ) ); - return radio; - } - - // - private ActionListener howToListener = new ActionListener() { - public void actionPerformed( ActionEvent e ) { - String howTo = e.getActionCommand(); - setPrefValue( DP_CALL_SERVICE, howTo ); - propertyChannel.put( DP_CALL_SERVICE, howTo ); - endpoint.setEnabled( howTo.equals( DP_CS_NEWURL ) ); - className.setEnabled( howTo.equals( DP_CS_CLASS ) ); - } - }; - - /******************************************************************************************************************* - * Create a specialized check box for "what to do with input/output"... - ******************************************************************************************************************/ - private JCheckBox createDataBox( String title, final String preferenceKey, boolean defaultValue ) { - boolean initValue = getPrefValue( preferenceKey, defaultValue ); - propertyChannel.put( preferenceKey, new Boolean( initValue ).toString() ); - return createCheckBox( title, initValue, -1, new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPrefValue( preferenceKey, enabled ); - propertyChannel.put( preferenceKey, new Boolean( enabled ).toString() ); - inFile.setEnabled( iFromFile.isSelected() ); - } - } ); - } - - /******************************************************************************************************************* - * Create a sub-panel for service inputs... - ******************************************************************************************************************/ - protected JPanel getInputPanel() { - JPanel inputData = new JPanel( new GridBagLayout() ); - inputData - .setBorder( createFatBorder( "Service Input Data", GraphColours.getColour( "cadetblue", Color.blue ) ) ); - - // upper part (tables, input file, show-xml check-box) - JPanel upper = new JPanel( new GridBagLayout() ); - - dataTablesPanel = new JPanel( new GridBagLayout() ); - - iFromFile = createDataBox( "Take an input from this XML file", DP_SC_IN_FILE, false ); - inFile = createFileSelector( "Select input XML for calling a service", "Select", null, DP_SC_INPUT_FILE, - DP_SC_INPUT_FILE ); - inFile.setEnabled( iFromFile.isSelected() ); - - iShowXML = createDataBox( "Show input as XML", DP_INP_SHOWXML, true ); - - SwingUtils.addComponent( upper, dataTablesPanel, 0, 0, 2, 1, BOTH, NWEST, 1.0, 1.0 ); - SwingUtils.addComponent( upper, iFromFile, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( upper, inFile, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( upper, iShowXML, 0, 2, 1, 1, NONE, NWEST, 0.0, 0.0 ); - - // lower part (console showing/editing input XML) - input = new EditableConsole(); - input.setAppendMode( false ); - input.setVerboseMode( false ); - - // split upper and lower parts into moving panels - JSplitPane split = vSplit( upper, input, 0.5 ); - SwingUtils.addComponent( inputData, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - return inputData; - } - - class EditableConsole extends CommonConsole { - - public EditableConsole() { - super(); - textArea.setEditable( true ); - textArea.setBackground( GraphColours.getColour( DashboardConfig.getString( P_S_EDIT_BGCOLOR, null ), - textArea.getBackground() ) ); - } - } - - /******************************************************************************************************************* - * Replace the global 'dataTablesPanel' with an information text. - ******************************************************************************************************************/ - protected void updateInputDataPanel( String info ) { - dataTablesPanel.removeAll(); - AwtUtils.redisplay( dataTablesPanel ); - - JLabel text = new JLabel( info ); - SwingUtils.addComponent( dataTablesPanel, text, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0 ); - dataTablesPanel.validate(); - return; - } - - /******************************************************************************************************************* - * Replace the global 'dataTablesPanel' with fields defining the input data for the given service. - ******************************************************************************************************************/ - protected void updateInputDataPanel( MobyService service, MobyDataType[] dataTypes ) { - dataTablesPanel.removeAll(); - - inputDataTables = new ServiceInputPanel( service, dataTypes ); - SwingUtils.addComponent( dataTablesPanel, inputDataTables, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - dataTablesPanel.validate(); - } - - /******************************************************************************************************************* - * Find 'dataTypeToBeFound in 'dataTypes' and return it. The same could be achieved by calling - * registryModel.getDataType() but here I do not want to create yet another swing worker for it. - ******************************************************************************************************************/ - protected MobyDataType findDataType( String dataTypeToBeFound, MobyDataType[] dataTypes ) { - for ( int i = 0; i < dataTypes.length; i++ ) { - if ( dataTypeToBeFound.equals( dataTypes[ i ].getName() ) ) return dataTypes[ i ]; - } - log.error( "Strange, data type '" + dataTypeToBeFound + "' was not found in " + dataTypes.length - + " data types." ); - return null; - } - - /******************************************************************************************************************* - * - * A worker that calls the service... - * - ******************************************************************************************************************/ - class MySwingWorker extends SwingWorker { - - MobyException exception = null; - DataContainer data = new DataContainer(); - boolean wasCancelled = false; - MobyService service; - - public MySwingWorker( MobyService service ) { - super(); - this.service = service; - data.setMetadata( propertyChannel ); - } - - public void cancel() { - wasCancelled = true; - propertyChannel.fire( DP_STATUS_MSG, "Service invocation cancelled." ); - } - - public Object construct() { - try { - runButton.setEnabled( false ); - propertyChannel.fire( DP_STATUS_MSG, "Calling service " + service.getName() + "..." ); - - // create a data container with input data... - if ( propertyChannel.getBoolean( DP_SC_IN_FILE, false ) ) { - - // ...either from a file - String inputFile = propertyChannel.getString( DP_SC_INPUT_FILE ); - if ( UUtils.isEmpty( inputFile ) ) throw new MobyException( "No input XML file given." ); - data.setDataFromFile( new File( inputFile ) ); - - } - else { - data.setData( inputDataTables.toXML() ); - } - - // optionally, show XML data: we want to show this XML - // input only (a) if it was explicitly asked for (property - // DP_INP_SHOWXML is true), or (b) if "no real service - // call" was selected (property DP_CALL_SERVICE has value - // DP_CS_NONE) - if ( DP_CS_NONE.equals( propertyChannel.getString( DP_CALL_SERVICE ) ) - || ( propertyChannel.getBoolean( DP_INP_SHOWXML, false ) ) ) { - input.setText( ( String ) data.getData() ); - } - - // If we are only pinging the service, set the data object to an empty message - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - String emptyMsg = "\n" - + "\n" + " \n" - + ""; - data.setData( emptyMsg ); - input.setText( emptyMsg ); - } - - // finally, call the service - stopButton.setEnabled( true ); - callerModel.runIt( data ); - - } - catch ( MobyException e ) { - exception = e; - - } - catch ( Error e ) { - exception = new MobyException( e.toString() ); - } - return null; // not used here - } - - // runs on the event-dispatching thread - public void finished() { - if ( wasCancelled ) { - // service was interrupted by the Stop button - do - // nothing (the whole GUI should be already in a good - // state - the button 'Stop' took care about it) - return; - } - - if ( exception == null ) { - - // handle results here (using renderers...) - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - propertyChannel.fire( DP_STATUS_MSG, service.getName() + " isAlive." ); - } - else { - propertyChannel.fire( DP_STATUS_MSG, "Service invocation finished." ); - } - - if ( !DP_CS_NONE.equals( propertyChannel.getString( DP_CALL_SERVICE ) ) ) { - results.updateComponent( data ); - } - - } - else { - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - propertyChannel.fire( DP_STATUS_MSG, service.getName() + " is dead." ); - results.removeResults(); - } - else { - propertyChannel.fire( DP_STATUS_MSG, "Service invocation failed." ); - error( CALLER_ERROR, exception ); - } - exception.printStackTrace(); - } - serviceFinished(); - } - } - - /******************************************************************************************************************* - * Called when a call to a service finished. - ******************************************************************************************************************/ - protected void serviceFinished() { - runButton.setEnabled( true ); - stopButton.setEnabled( false ); - } - - /******************************************************************************************************************* - * Called when a service is selected in a service tree (or in a 'recently used services' combo box), and also at the - * beginning when a service name is retrieved from user preferences. - * - * Get selected service from a registry model and generate a new 'input data panel' to reflect input data of the - * selected service. - ******************************************************************************************************************/ - protected void selectService( final String serviceName ) { - final Object source = this; - final SwingWorker worker = new SwingWorker() { - MobyService service; - MobyDataType[] dataTypes; - - public Object construct() { - try { - service = registryModel.getService( serviceName ); - dataTypes = registryModel.getDataTypes( source ); - } - catch ( MobyException e ) { - error( ServicesTree.SERVICES_ACCESS_ERROR, e ); - } - return service; // not used here - } - - // runs on the event-dispatching thread. - public void finished() { - if ( service == null ) { - deselectService(); - } - else { - updateInputDataPanel( service, dataTypes ); - selService.setText( service.getName() ); - // selectionAllowed = false; - // recentServices.setText (service.getName()); - // selectionAllowed = true; - propertyChannel.put( DP_SC_SERVICE, service ); - runButton.setEnabled( true ); - - } - } - }; - worker.start(); - } - - /******************************************************************************************************************* - * Called when no service is selected in order to display this fact on various places in the panel. - ******************************************************************************************************************/ - protected void deselectService() { - selService.setText( "" ); - updateInputDataPanel( INIT_SELECT ); - propertyChannel.remove( DP_SC_SERVICE ); - runButton.setEnabled( false ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getName() { - return "Simple Client"; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getDescription() { - return "A panel allowing to create input data and to call an arbitrary Biomoby service. " - + "Its purpose is mostly for the service developers to test their new services."; - } - - /******************************************************************************************************************* - * - * Customized tree of services... - * - ******************************************************************************************************************/ - protected class CustomServicesTree extends ServicesTree { - - /*************************************************************************************************************** - * Construtor - **************************************************************************************************************/ - public CustomServicesTree( RegistryModel model, CommonConsole console ) { - super( model, console ); - } - - /*************************************************************************************************************** - * - **************************************************************************************************************/ - protected void createPopups( String title ) { - super.createPopups( title ); - removeFromPopups( AC_RELOAD ); - removeSeparatorAfter( AC_COLLAPSE ); - } - - /*************************************************************************************************************** - * Service selected in a service tree... - **************************************************************************************************************/ - protected void selected( DefaultMutableTreeNode node ) { - if ( node == null ) { - // nothing selected - deselectService(); - return; - } - updateInputDataPanel( "Loading..." ); - selService.setText( "" ); - final CommonNode nodeObject = ( CommonNode ) node.getUserObject(); - String currentServiceName = nodeObject.getValue(); - selectService( currentServiceName ); - setPrefValue( DP_SC_SERVICE_NAME, currentServiceName ); - } - } - -} +// SimpleClientPanel.java +// +// Created: December 2005 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.service.dashboard; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.Date; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.ButtonGroup; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JRadioButton; +import javax.swing.JSplitPane; +import javax.swing.JTextField; +import javax.swing.tree.DefaultMutableTreeNode; + +import org.biomoby.service.dashboard.data.DataContainer; +import org.biomoby.service.dashboard.data.ServiceInputPanel; +import org.biomoby.shared.MobyDataType; +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.tulsoft.shared.UUtils; +import org.tulsoft.tools.gui.AwtUtils; +import org.tulsoft.tools.gui.JFileChooserWithHistory; +import org.tulsoft.tools.gui.JTextFieldWithHistory; +import org.tulsoft.tools.gui.SwingUtils; + +/** + * A panel allowing to formulate input data and to call an arbitrary + * Biomoby service. Its interface is however not that user-friendly, + * and it is supposed to be used more or less for testing purposes in + * time when a new service is being created and developed.

+ * + * @author Martin Senger + * @version $Id$ + */ + +public class SimpleClientPanel + extends AbstractPanel { + + private static org.apache.commons.logging.Log log = + org.apache.commons.logging.LogFactory.getLog (SimpleClientPanel.class); + + /** A property name. Its value contains a name of color that will + * be used to display service name. + */ + protected static final String P_S_TITLE_COLOR = "simpleclient.service.title.color"; + + /** A property name. Its value contains a name of color that will + * be used as background for editable console with XML input. + */ + protected static final String P_S_EDIT_BGCOLOR = "simpleclient.service.edit.bgcolor"; + + // some texts + protected static final String INIT_SELECT = + "

Start by selecting a service
" + + "that you wish to call.
"; + + protected static final String CALLER_ERROR = + "Sorry, an error happened when calling a service.\n\n"; + + protected static final Insets BREATH_UP = new Insets (6,6,0,6); + protected static final Insets BREATH_DOWN = new Insets (0,6,6,6); + + // associated models working behind the scene + RegistryModel registryModel; + ServiceCallerModel callerModel; + + // components that are used from more methods + JLabel selService; + CommonConsole input; + JFileChooserWithHistory outFile, inFile; + JButton runButton, stopButton; + JCheckBox iShowXML, iFromFile; + JTextFieldWithHistory className, endpoint; + JPanel dataTablesPanel; + ServiceInputPanel inputDataTables; + MySwingWorker runWorker; + ResultsPanel results; + JComponent resultsComp; + JSplitPane resSplit; +// JTextFieldWithHistory recentServices; + + boolean selectionAllowed = false; + + // shared icons + protected static Icon runIcon, runIconDis; + protected static Icon stopIcon, stopIconDis; + protected static Icon addDataIcon, addDataIconDis; + + /********************************************************************* + * Default constructor. + ********************************************************************/ + public SimpleClientPanel() { + super(); + panelIconFileName = "images/debug.gif"; + } + + /********************************************************************* + * Load shared icons. + ********************************************************************/ + protected void loadIcons() { + super.loadIcons(); + + if (runIcon == null) runIcon = loadIcon ("images/smallRun.gif"); + if (runIconDis == null) runIconDis = loadIcon ("images/smallRun_dis.gif"); + + if (stopIcon == null) stopIcon = loadIcon ("images/smallCancel.gif"); + if (stopIconDis == null) stopIconDis = loadIcon ("images/smallCancel_dis.gif"); + + if (addDataIcon == null) addDataIcon = loadIcon ("images/smallAnnotate.gif"); + if (addDataIconDis == null) addDataIconDis = loadIcon ("images/smallAnnonate_dis.gif"); + + } + + /************************************************************************** + * + **************************************************************************/ + public JComponent getComponent (PropertyChannel aPropertyChannel) { + setPropertyChannel (aPropertyChannel); + registryModel = createRegistryModel(); + callerModel = new ServiceCallerModel(); + callerModel.setPropertyChannel (aPropertyChannel); + + if (pComponent != null) return pComponent; + pComponent = new JPanel (new GridBagLayout(), true); + + // result panel + results = new ResultsPanel(); + resultsComp = results.getComponent (aPropertyChannel); + propertyChannel.addPropertyChangeListener (new PropertyChangeListener() { + public void propertyChange (PropertyChangeEvent e) { + if (DP_DETACH_VIEW.equals (e.getPropertyName())) { + + MobyService srv = + (MobyService)propertyChannel.get (DP_SC_SERVICE); + String title = (srv == null ? "Service results" : + srv.getName() + " at " + new Date()); + JComponent current = results.getComponent (propertyChannel); + results.adjustForDetachement(); + JFrame newFrame = + SwingUtils.createSoftMainFrame (current, + title); + Dimension dim = current.getPreferredSize(); + SwingUtils.showMainFrameRelativeTo + (pComponent, newFrame, (int)dim.getWidth(), (int)dim.getHeight()); + results = new ResultsPanel(); + resultsComp = results.getComponent (propertyChannel); + resSplit.setBottomComponent (resultsComp); + } + }}); + + + // panel with all the fields (except for building inputs) + JPanel controls = getControlPanel(); + + // panel with input data + JPanel inputData = getInputPanel(); + updateInputDataPanel (INIT_SELECT); + + // service ontology tree + JPanel sBoard = new JPanel (new GridBagLayout()); +// JLabel lRecent = new JLabel ("Recently called services"); +// recentServices = createText (null, +// DP_SC_SERVICES, +// DP_SC_SERVICES); +// recentServices.addActionListener (new ActionListener() { +// public void actionPerformed (ActionEvent e) { +// String contents = ((JTextFieldWithHistory)e.getSource()).getText(); +// if (! "".equals (contents) && selectionAllowed) { +// System.out.println ("SEL: " + contents); +// selectService (contents); +// } +// } +// }); + + ServicesBoard servicesBoard = + new ServicesBoard (registryModel, + null, + propertyChannel, + new CustomServicesTree (registryModel, + null)); + log.debug ("Services tree update started"); + servicesBoard.updateTree (CommonTree.SORTED_BY_AUTHORITY); +// SwingUtils.addComponent (sBoard, lRecent, 0, 0, 1, 1, NONE, NWEST, 0.0, 0.0, BREATH_UP); +// SwingUtils.addComponent (sBoard, recentServices, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0, BREATH_DOWN); + SwingUtils.addComponent (sBoard, servicesBoard, 0, 2, 1, 1, BOTH, NWEST, 1.0, 1.0); + + // split it into moving panels + JSplitPane split = hSplit (resSplit = vSplit (hSplit (controls, + sBoard, 0.5), + resultsComp, 0.1), + inputData, + 0.5); + + SwingUtils.addComponent (pComponent, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + + // initialize by a last used service name from preferences + String lastServiceName = getPrefValue (DP_SC_SERVICE_NAME, ""); + if (! "".equals (lastServiceName)) + selectService (lastServiceName); + + return pComponent; + } + + /************************************************************************** + * Create a sub-panel for all the controls... + **************************************************************************/ + protected JPanel getControlPanel() { + JPanel p = new JPanel (new GridBagLayout()); + + // (selected) service name + selService = new JLabel(); + selService.setFont (FAT_BORDER_FONT); + selService.setForeground + (GraphColours.getColour (DashboardConfig.getString (P_S_TITLE_COLOR, null), + Color.blue)); + + // how to invoke the service + JPanel howTo = createTitledPanel ("Service invocation"); + endpoint = createText (null, DP_ENDPOINT, DP_ENDPOINT); + className = createText (null, DP_IMPL_CLASS, DP_IMPL_CLASS); + + ButtonGroup group = new ButtonGroup(); + JRadioButton htNone, htRegistry, htEndpoint, htLocal, htNewURL; + group.add (htEndpoint = createHowToButton ("Use service's usual endpoint", DP_CS_URL)); + htNone = createHowToButton ("No real call, just show/echo input", DP_CS_NONE); + htNone.addItemListener( + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + if (enabled) runButton.setText(" Show Input "); + else { + if (propertyChannel.getBoolean(DP_INP_PING, false)){ + runButton.setText(" Ping Service "); + } + else { + runButton.setText(" Call Service "); + } + } + } + }); + group.add (htNone); + group.add (htRegistry = createHowToButton ("Ask registry where service is, and call it", DP_CS_REGISTRY)); + group.add (htNewURL = createHowToButton ("Use this endpoint", DP_CS_NEWURL)); + group.add (htLocal = createHowToButton ("Use this local class", DP_CS_CLASS)); + + // run the service + // determine button text from preferences + boolean usingPing = getPrefValue (DP_INP_PING, false); + boolean usingAsBytes = getPrefValue (DP_INP_ASBYTES, false); + String runLabel = " Call Service "; + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runLabel = " Show Input "; + else if (usingPing) runLabel = " Ping Service "; + + runButton = + createButton (runLabel, + "Invoke selected service", + KeyEvent.VK_C, + new ActionListener() { + public void actionPerformed (ActionEvent e) { + MobyService srv = (MobyService)propertyChannel.get (DP_SC_SERVICE); + if (srv != null) { + // if the service requires authentication this is asked + if(propertyChannel.getBoolean(DP_AUTHENTICATION, false)) { + askForAuthentication(); + } + // remove possible remnants + else { + propertyChannel.remove(DP_USER_AUTHENTICATION); + propertyChannel.remove(DP_PASSWORD_AUTHENTICATION); + } + runWorker = new MySwingWorker (srv); + runWorker.start(); + } + } + }); + runButton.setIcon (runIcon); + runButton.setDisabledIcon (runIconDis); + runButton.setEnabled (false); // will enable when a service is selected + + stopButton = + createButton (" Stop service ", + "Cancel connection to a running service", + KeyEvent.VK_S, + new ActionListener() { + public void actionPerformed (ActionEvent e) { + if (runWorker != null) { +// runWorker.interrupt(); // no sense with the current Biomoby API + runWorker.cancel(); + } + serviceFinished(); + } + }); + stopButton.setIcon (stopIcon); + stopButton.setDisabledIcon (stopIconDis); + stopButton.setEnabled (false); // will enable when a service is called + + JPanel buttonPanel = createButtonPanel (new JButton[] { runButton, + stopButton }); + + JCheckBox asPing = createCheckBox + ("'Ping' this service", + usingPing, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPropertySelect (enabled, DP_INP_PING); + setPrefValue (DP_INP_PING, enabled); + propertyChannel.put (DP_INP_PING, + new Boolean (enabled).toString()); + if (enabled) { + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runButton.setText(" Show Input "); + else + runButton.setText(" Ping Service "); + } + else { + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runButton.setText(" Show Input "); + else + runButton.setText(" Call Service "); + } + } + }); + setPropertySelect (usingPing, DP_INP_PING); + asPing.setToolTipText ("A Moby 'Ping' is used to determine if the service is responsive " + + "and if it responds in an API-compliant manner."); + Font font = asPing.getFont(); + asPing.setFont (font.deriveFont (Math.max (1, font.getSize2D() - 1))); + + JCheckBox asBytes = createCheckBox + ("Send data to service as a byte array", + usingAsBytes, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPropertySelect (enabled, DP_INP_ASBYTES); + setPrefValue (DP_INP_ASBYTES, enabled); + propertyChannel.put (DP_INP_ASBYTES, + new Boolean (enabled).toString()); + } + }); + setPropertySelect (usingAsBytes, DP_INP_ASBYTES); + asBytes.setToolTipText ("It should not have any effect on result; it is for debugging"); + font = asBytes.getFont(); + asBytes.setFont (font.deriveFont (Math.max (1, font.getSize2D() - 1))); + + JCheckBox authenticationBox = createCheckBox("Use a user/password for service authentication", false, -1, + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + propertyChannel.put(DP_AUTHENTICATION, e.getStateChange() == ItemEvent.SELECTED); + } + }); + authenticationBox.setToolTipText("If the service requires authentication." + + "A dialog will open if you call the service to enter the authentication."); + font = authenticationBox.getFont(); + authenticationBox.setFont(font.deriveFont(Math.max(1, font.getSize2D() -1))); + + SwingUtils.addComponent (howTo, htEndpoint, 0, 0, 2, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htNewURL, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, endpoint, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htRegistry, 0, 2, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, htLocal, 0, 3, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, className, 1, 3, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htNone, 0, 4, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, asPing, 0, 5, 2, 1, NONE, NWEST, 0.0, 0.0, BREATH_TOP); + SwingUtils.addComponent (howTo, asBytes, 0, 6, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, authenticationBox,0,7,2,1,NONE, NWEST, 0,0); + + Component glue = Box.createVerticalGlue(); + SwingUtils.addComponent (p, selService, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0); + SwingUtils.addComponent (p, howTo, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (p, buttonPanel, 0, 2, 1, 1, NONE, CENTER, 0.0, 0.0, BREATH_TOP); + SwingUtils.addComponent (p, glue, 0, 3, 1, 1, VERT, NWEST, 0.0, 1.0); + return p; + } + + /** + * Opens a dialog to enter the authentication information + */ + private void askForAuthentication() { + final JDialog dialog = new JDialog( new JFrame(), "Authentication", true ); + JPanel panel = new JPanel( new GridBagLayout() ); + panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); + + Insets insets = new Insets( 4, 4, 4, 4 ); + + JLabel label = new JLabel( "Please enter your username and password !" ); + SwingUtils.addComponent( panel, label, 0, 0, 2, 1, HORI, CENTER, 1, 0, insets ); + + label = new JLabel( "User: " ); + SwingUtils.addComponent( panel, label, 0, 1, 1, 1, HORI, NWEST, 0, 0, insets ); + + final JTextField userField = new JTextField( propertyChannel.getString( DP_USER_AUTHENTICATION ), 20 ); + SwingUtils.addComponent( panel, userField, 1, 1, 1, 1, HORI, NWEST, 0, 0, insets ); + + label = new JLabel( "Password: " ); + SwingUtils.addComponent( panel, label, 0, 2, 1, 1, HORI, NWEST, 0, 0, insets ); + + final JPasswordField passwordField = new JPasswordField( + propertyChannel.getString( DP_PASSWORD_AUTHENTICATION ), 20 ); + SwingUtils.addComponent( panel, passwordField, 1, 2, 1, 1, HORI, NWEST, 0, 0, insets ); + + JButton button = new JButton( "Enter..." ); + button.addActionListener( new ActionListener() { + public void actionPerformed( ActionEvent e ) { + // sets the user and password in the propertychannel + propertyChannel.put( DP_USER_AUTHENTICATION, userField.getText() ); + propertyChannel.put( DP_PASSWORD_AUTHENTICATION, new String(passwordField.getPassword() )); + + dialog.setVisible( false ); + } + } ); + SwingUtils.addComponent( panel, button, 0, 3, 2, 1, HORI, CENTER, 0, 0, insets ); + + dialog.setContentPane( panel ); + dialog.pack(); + dialog.setLocationRelativeTo( this ); + dialog.setVisible( true ); + } + + /************************************************************************** + * Select/unselect using 'send as bytes' or 'ping'... + **************************************************************************/ + protected void setPropertySelect (boolean enabled, String property) { + setPrefValue (property, enabled); + propertyChannel.put (property, new Boolean (enabled).toString()); + } + + /************************************************************************** + * Create a specialized radio button - for various ways how to + * call a service. + **************************************************************************/ + private JRadioButton createHowToButton (String title, String howTo) { + JRadioButton radio = new JRadioButton (title); + radio.setActionCommand (howTo); + radio.addActionListener (howToListener); + String initHowTo = getPrefValue (DP_CALL_SERVICE, DP_CS_NONE); + if (howTo.equals (initHowTo)) { + radio.setSelected (true); + radio.setEnabled (true); + propertyChannel.put (DP_CALL_SERVICE, howTo); + } + endpoint.setEnabled (initHowTo.equals (DP_CS_NEWURL)); + className.setEnabled (initHowTo.equals (DP_CS_CLASS)); + return radio; + } + + // + private ActionListener howToListener = new ActionListener() { + public void actionPerformed (ActionEvent e) { + String howTo = e.getActionCommand(); + setPrefValue (DP_CALL_SERVICE, howTo); + propertyChannel.put (DP_CALL_SERVICE, howTo); + endpoint.setEnabled (howTo.equals (DP_CS_NEWURL)); + className.setEnabled (howTo.equals (DP_CS_CLASS)); + } + }; + + /************************************************************************** + * Create a specialized check box for "what to do with input/output"... + **************************************************************************/ + private JCheckBox createDataBox (String title, + final String preferenceKey, + boolean defaultValue) { + boolean initValue = getPrefValue (preferenceKey, defaultValue); + propertyChannel.put (preferenceKey, + new Boolean (initValue).toString()); + return createCheckBox + (title, initValue, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPrefValue (preferenceKey, enabled); + propertyChannel.put (preferenceKey, + new Boolean (enabled).toString()); + inFile.setEnabled (iFromFile.isSelected()); + } + }); + } + + /************************************************************************** + * Create a sub-panel for service inputs... + **************************************************************************/ + protected JPanel getInputPanel() { + JPanel inputData = new JPanel (new GridBagLayout()); + inputData.setBorder (createFatBorder + ("Service Input Data", + GraphColours.getColour ("cadetblue", Color.blue))); + + // upper part (tables, input file, show-xml check-box) + JPanel upper = new JPanel (new GridBagLayout()); + + dataTablesPanel = new JPanel (new GridBagLayout()); + + iFromFile = createDataBox ("Take an input from this XML file", DP_SC_IN_FILE, false); + inFile = createFileSelector ("Select input XML for calling a service", + "Select", + null, + DP_SC_INPUT_FILE, + DP_SC_INPUT_FILE); + inFile.setEnabled (iFromFile.isSelected()); + + iShowXML = createDataBox ("Show input as XML", DP_INP_SHOWXML, true); + + SwingUtils.addComponent (upper, dataTablesPanel, 0, 0, 2, 1, BOTH, NWEST, 1.0, 1.0); + SwingUtils.addComponent (upper, iFromFile, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (upper, inFile, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (upper, iShowXML, 0, 2, 1, 1, NONE, NWEST, 0.0, 0.0); + + // lower part (console showing/editing input XML) + input = new EditableConsole(); + input.setAppendMode (false); + input.setVerboseMode (false); + + // split upper and lower parts into moving panels + JSplitPane split = vSplit (upper, input, 0.5); + SwingUtils.addComponent (inputData, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + return inputData; + } + + class EditableConsole + extends CommonConsole { + + public EditableConsole() { + super(); + textArea.setEditable (true); + textArea.setBackground + (GraphColours.getColour (DashboardConfig.getString (P_S_EDIT_BGCOLOR, null), + textArea.getBackground())); + } + } + + /************************************************************************** + * Replace the global 'dataTablesPanel' with an information text. + **************************************************************************/ + protected void updateInputDataPanel (String info) { + dataTablesPanel.removeAll(); + AwtUtils.redisplay (dataTablesPanel); + + JLabel text = new JLabel (info); + SwingUtils.addComponent (dataTablesPanel, text, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0); + dataTablesPanel.validate(); + return; + } + + /************************************************************************** + * Replace the global 'dataTablesPanel' with fields defining the + * input data for the given service. + **************************************************************************/ + protected void updateInputDataPanel (MobyService service, + MobyDataType[] dataTypes) { + dataTablesPanel.removeAll(); + + inputDataTables = new ServiceInputPanel (service, dataTypes); + SwingUtils.addComponent (dataTablesPanel, inputDataTables, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + dataTablesPanel.validate(); + } + + /************************************************************************** + * Find 'dataTypeToBeFound in 'dataTypes' and return it. The same + * could be achieved by calling registryModel.getDataType() but + * here I do not want to create yet another swing worker for it. + **************************************************************************/ + protected MobyDataType findDataType (String dataTypeToBeFound, + MobyDataType[] dataTypes) { + for (int i = 0; i < dataTypes.length; i++) { + if (dataTypeToBeFound.equals (dataTypes[i].getName())) + return dataTypes[i]; + } + log.error ("Strange, data type '" + dataTypeToBeFound + + "' was not found in " + dataTypes.length + " data types."); + return null; + } + + /************************************************************************** + * + * A worker that calls the service... + * + **************************************************************************/ + class MySwingWorker + extends SwingWorker { + + MobyException exception = null; + DataContainer data = new DataContainer(); + boolean wasCancelled = false; + MobyService service; + + public MySwingWorker (MobyService service) { + super(); + this.service = service; + data.setMetadata (propertyChannel); + } + + public void cancel() { + wasCancelled = true; + propertyChannel.fire (DP_STATUS_MSG, "Service invocation cancelled."); + } + + public Object construct() { + try { + runButton.setEnabled (false); + propertyChannel.fire (DP_STATUS_MSG, + "Calling service " + service.getName() + "..."); + + // create a data container with input data... + if (propertyChannel.getBoolean (DP_SC_IN_FILE, false)) { + + // ...either from a file + String inputFile = propertyChannel.getString (DP_SC_INPUT_FILE); + if (UUtils.isEmpty (inputFile)) + throw new MobyException ("No input XML file given."); + data.setDataFromFile (new File (inputFile)); + + } else { + data.setData (inputDataTables.toXML()); + } + + // optionally, show XML data: we want to show this XML + // input only (a) if it was explicitly asked for (property + // DP_INP_SHOWXML is true), or (b) if "no real service + // call" was selected (property DP_CALL_SERVICE has value + // DP_CS_NONE) + if ( DP_CS_NONE.equals (propertyChannel.getString (DP_CALL_SERVICE)) || + (propertyChannel.getBoolean (DP_INP_SHOWXML, false)) ) { + input.setText ((String)data.getData()); + } + + // If we are only pinging the service, set the data object to an empty message + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + String emptyMsg = "\n" + + "\n" + + " \n" + + ""; + data.setData(emptyMsg); + input.setText(emptyMsg); + } + + // finally, call the service + stopButton.setEnabled (true); + callerModel.runIt (data); + + } catch (MobyException e) { + exception = e; + + } catch (Error e) { + exception = new MobyException (e.toString()); + } + return null; // not used here + } + + // runs on the event-dispatching thread + public void finished() { + if (wasCancelled) { + // service was interrupted by the Stop button - do + // nothing (the whole GUI should be already in a good + // state - the button 'Stop' took care about it) + return; + } + + if (exception == null) { + + // handle results here (using renderers...) + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + propertyChannel.fire (DP_STATUS_MSG, service.getName()+" isAlive."); + } else { + propertyChannel.fire (DP_STATUS_MSG, "Service invocation finished."); + } + + if (! DP_CS_NONE.equals (propertyChannel.getString (DP_CALL_SERVICE))) { + results.updateComponent (data); + } + + } else { + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + propertyChannel.fire (DP_STATUS_MSG, service.getName()+" is dead."); + results.removeResults(); + } else { + propertyChannel.fire (DP_STATUS_MSG, "Service invocation failed."); + error (CALLER_ERROR, exception); + } + exception.printStackTrace(); + } + serviceFinished(); + } + } + + /************************************************************************** + * Called when a call to a service finished. + **************************************************************************/ + protected void serviceFinished() { + runButton.setEnabled (true); + stopButton.setEnabled (false); + } + + /************************************************************************** + * Called when a service is selected in a service tree (or in a + * 'recently used services' combo box), and also at the beginning + * when a service name is retrieved from user preferences. + * + * Get selected service from a registry model and generate a new + * 'input data panel' to reflect input data of the selected + * service. + **************************************************************************/ + protected void selectService (final String serviceName) { + final Object source = this; + final SwingWorker worker = new SwingWorker() { + MobyService service; + MobyDataType[] dataTypes; + public Object construct() { + try { + service = registryModel.getService (serviceName); + dataTypes = registryModel.getDataTypes (source); + } catch (MobyException e) { + error (ServicesTree.SERVICES_ACCESS_ERROR, e); + } + return service; // not used here + } + + // runs on the event-dispatching thread. + public void finished() { + if (service == null) { + deselectService(); + } else { + updateInputDataPanel (service, dataTypes); + selService.setText (service.getName()); +// selectionAllowed = false; +// recentServices.setText (service.getName()); +// selectionAllowed = true; + propertyChannel.put (DP_SC_SERVICE, service); + runButton.setEnabled (true); + + } + } + }; + worker.start(); + } + + /************************************************************************** + * Called when no service is selected in order to display this + * fact on various places in the panel. + **************************************************************************/ + protected void deselectService() { + selService.setText (""); + updateInputDataPanel (INIT_SELECT); + propertyChannel.remove (DP_SC_SERVICE); + runButton.setEnabled (false); + } + + /************************************************************************** + * + **************************************************************************/ + public String getName() { + return "Simple Client"; + } + + /************************************************************************** + * + **************************************************************************/ + public String getDescription() { + return + "A panel allowing to create input data and to call an arbitrary Biomoby service. " + + "Its purpose is mostly for the service developers to test their new services."; + } + + /************************************************************************** + * + * Customized tree of services... + * + **************************************************************************/ + protected class CustomServicesTree + extends ServicesTree { + + /********************************************************************* + * Construtor + ********************************************************************/ + public CustomServicesTree (RegistryModel model, + CommonConsole console) { + super (model, console); + } + + /********************************************************************* + * + ********************************************************************/ + protected void createPopups (String title) { + super.createPopups (title); + removeFromPopups (AC_RELOAD); + removeSeparatorAfter (AC_COLLAPSE); + } + + /********************************************************************* + * Service selected in a service tree... + ********************************************************************/ + protected void selected (DefaultMutableTreeNode node) { + if (node == null) { + // nothing selected + deselectService(); + return; + } + updateInputDataPanel ("Loading..."); + selService.setText (""); + final CommonNode nodeObject = (CommonNode)node.getUserObject(); + String currentServiceName = nodeObject.getValue(); + selectService (currentServiceName); + setPrefValue (DP_SC_SERVICE_NAME, currentServiceName); + } + } + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java 2008/11/26 08:54:21 1.7 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java 2008/12/03 15:21:13 1.8 @@ -1,168 +1,180 @@ -// ServiceCallerModel.java -// -// Created: February 2006 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.service.dashboard; - -import org.apache.axis.client.Call; -import org.biomoby.client.ExtendedProtocolClient; -import org.biomoby.client.ExtendedServiceLocator; -import org.biomoby.client.MobyServiceLocator; -import org.biomoby.service.dashboard.data.DataContainer; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.parser.MobyJob; -import org.biomoby.shared.parser.MobyPackage; -import org.tulsoft.shared.UUtils; - -/** - * A model that achieves its task by calling (local, remote, or none) Biomoby service. It delegates the task of calling - * a service to a true Biomoby client (that extends BaseClient). - *

- * - * @author Martin Senger - * @version $Id$ - */ - -public class ServiceCallerModel extends AbstractModel { - - // private static org.apache.commons.logging.Log log = - // org.apache.commons.logging.LogFactory.getLog (ServiceCallerModel.class); - - /******************************************************************************************************************* - * Call a service. This is the main purpose of this model. - *

- * - * @param data - * contains input data and this method replaces them by result data - ******************************************************************************************************************/ - public void runIt( DataContainer data ) throws MobyException { - SimpleClient worker = new SimpleClient( data ); - worker.process(); - } - - /******************************************************************************************************************* - * - * A real client - the main worker for this model.. - * - ******************************************************************************************************************/ - protected class SimpleClient extends ExtendedProtocolClient { - - DataContainer data; - - /*************************************************************************************************************** - * Constructor. - **************************************************************************************************************/ - public SimpleClient( DataContainer data ) { - super(); - this.data = data; - } - - /*************************************************************************************************************** - * What service to call and where to find it. - **************************************************************************************************************/ - public MobyServiceLocator getServiceLocator() throws MobyException { - return new MyServiceLocator(); - } - - /*************************************************************************************************************** - * Not used here... - **************************************************************************************************************/ - public boolean fillRequest( MobyJob request, MobyPackage inputContext ) throws MobyException { - return true; - } - - /*************************************************************************************************************** - * Not used here... - **************************************************************************************************************/ - public boolean useResponse( MobyJob response, MobyPackage responseContext ) throws MobyException { - return true; - } - - /*************************************************************************************************************** - * Return input XML (from a data container obtained in the constructor). - **************************************************************************************************************/ - public String fillRequest() throws MobyException { - - if ( data == null ) throw new MobyException( "No input data given." ); - - return ( String ) data.getData(); - } - - /** - * Sets the authentication for the service call. If the user has checked the corresponding box in the Dashboard - * the values are stored in the propertychannel. - */ - protected void setAuthentication( Call call ) { - String user = propertyChannel.getString( DashboardProperties.DP_USER_AUTHENTICATION ); - if ( !isEmpty( user ) ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, new String( ( char[] ) propertyChannel - .get( DashboardProperties.DP_PASSWORD_AUTHENTICATION ) ) ); - } - } - - /*************************************************************************************************************** - * - **************************************************************************************************************/ - public boolean useResponse( String xmlResponse ) throws MobyException { - - data.setData( xmlResponse ); - - // do nothing more if it is just an input echo - if ( ( ( ExtendedServiceLocator ) getServiceLocator() ).isLoop() ) return false; - - return false; - } - } - - /******************************************************************************************************************* - * - * A service locator filled from the property channel. - * - ******************************************************************************************************************/ - protected class MyServiceLocator extends ExtendedServiceLocator { - - public MyServiceLocator() throws MobyException { - super(); - - // fill this locator by a service - MobyService selService = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - if ( selService == null ) throw new MobyException( "No service given." ); - MobyService clonedService = new MobyService( selService.getName(), selService.getAuthority() ); - clonedService.setURL( selService.getURL() ); - setService( clonedService ); - - // fill how to call this service - String howToCall = propertyChannel.getString( DP_CALL_SERVICE ); - if ( DP_CS_NEWURL.equals( howToCall ) ) { - String sEndpoint = propertyChannel.getString( DP_ENDPOINT ); - if ( !UUtils.isEmpty( sEndpoint ) ) clonedService.setURL( sEndpoint ); - - } - else if ( DP_CS_REGISTRY.equals( howToCall ) ) { - clonedService.setURL( null ); - setRegistryEndpoint( propertyChannel.getString( DP_REGISTRY_ENDPOINT ) ); - setRegistryNamespace( propertyChannel.getString( DP_REGISTRY_NAMESPACE ) ); - - } - else if ( DP_CS_CLASS.equals( howToCall ) ) { - String localClass = propertyChannel.getString( DP_IMPL_CLASS ); - if ( UUtils.isEmpty( localClass ) ) throw new MobyException( "No local class given." ); - setLocalClass( localClass ); - - } - else if ( DP_CS_NONE.equals( howToCall ) ) { - setLoop( true ); - } - - setAsBytes( propertyChannel.getBoolean( DP_INP_ASBYTES, false ) ); - - } - } - -} +// ServiceCallerModel.java +// +// Created: February 2006 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.service.dashboard; + +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.parser.MobyPackage; +import org.biomoby.shared.parser.MobyJob; +import org.biomoby.client.ExtendedProtocolClient; +import org.biomoby.client.MobyServiceLocator; +import org.biomoby.client.ExtendedServiceLocator; +import org.biomoby.service.dashboard.data.DataContainer; + +import org.tulsoft.shared.UUtils; + +/** + * A model that achieves its task by calling (local, remote, or none) + * Biomoby service. It delegates the task of calling a service to a + * true Biomoby client (that extends BaseClient).

+ * + * @author Martin Senger + * @version $Id$ + */ + +public class ServiceCallerModel + extends AbstractModel { + +// private static org.apache.commons.logging.Log log = +// org.apache.commons.logging.LogFactory.getLog (ServiceCallerModel.class); + + /************************************************************************** + * Call a service. This is the main purpose of this model.

+ * + * @param data contains input data and this method replaces them + * by result data + *************************************************************************/ + public void runIt (DataContainer data) + throws MobyException { + SimpleClient worker = new SimpleClient (data); + worker.process(); + } + + /************************************************************************** + * + * A real client - the main worker for this model.. + * + *************************************************************************/ + protected class SimpleClient + extends ExtendedProtocolClient { + + DataContainer data; + + /************************************************************************** + * Constructor. + *************************************************************************/ + public SimpleClient (DataContainer data) { + super(); + this.data = data; + } + + /************************************************************************** + * What service to call and where to find it. + *************************************************************************/ + public MobyServiceLocator getServiceLocator() + throws MobyException { + return new MyServiceLocator(); + } + + /************************************************************************** + * Not used here... + *************************************************************************/ + public boolean fillRequest (MobyJob request, MobyPackage inputContext) + throws MobyException { + return true; + } + + /************************************************************************** + * Not used here... + *************************************************************************/ + public boolean useResponse (MobyJob response, + MobyPackage responseContext) + throws MobyException { + return true; + } + + /************************************************************************** + * Return input XML (from a data container obtained in the + * constructor). + *************************************************************************/ + public String fillRequest() + throws MobyException { + + if (data == null) + throw new MobyException ("No input data given."); + + return (String)data.getData(); + } + + /************************************************************************** + * + *************************************************************************/ + public boolean useResponse (String xmlResponse) + throws MobyException { + + data.setData (xmlResponse); + + // do nothing more if it is just an input echo + if ( ((ExtendedServiceLocator)getServiceLocator()).isLoop()) + return false; + + return false; + } + } + + /************************************************************************** + * + * A service locator filled from the property channel. + * + *************************************************************************/ + protected class MyServiceLocator + extends ExtendedServiceLocator { + + public MyServiceLocator() + throws MobyException { + super(); + + // fill this locator by a service + MobyService selService = (MobyService)propertyChannel.get (DP_SC_SERVICE); + if (selService == null) + throw new MobyException ("No service given."); + MobyService clonedService = new MobyService (selService.getName(), selService.getAuthority()); + clonedService.setURL (selService.getURL()); + setService (clonedService); + + // fill how to call this service + String howToCall = propertyChannel.getString (DP_CALL_SERVICE); + if (DP_CS_NEWURL.equals (howToCall)) { + String sEndpoint = propertyChannel.getString (DP_ENDPOINT); + if (! UUtils.isEmpty (sEndpoint)) + clonedService.setURL (sEndpoint); + + } else if (DP_CS_REGISTRY.equals (howToCall)) { + clonedService.setURL (null); + setRegistryEndpoint (propertyChannel.getString (DP_REGISTRY_ENDPOINT)); + setRegistryNamespace (propertyChannel.getString (DP_REGISTRY_NAMESPACE)); + + } else if (DP_CS_CLASS.equals (howToCall)) { + String localClass = propertyChannel.getString (DP_IMPL_CLASS); + if (UUtils.isEmpty (localClass)) + throw new MobyException ("No local class given."); + setLocalClass (localClass); + + } else if (DP_CS_NONE.equals (howToCall)) { + setLoop (true); + } + + setAsBytes (propertyChannel.getBoolean (DP_INP_ASBYTES, false)); + + // sets the user and the password + // the getString method returns an empty string in case the + // key is not in the propertychannel, therefore the test if + // the value is not empty + String user = propertyChannel.getString(DP_USER_AUTHENTICATION); + if(user.length() > 0) { + setUser( user ); + } + String password = propertyChannel.getString(DP_PASSWORD_AUTHENTICATION); + if(password.length() > 0) { + setPassword( password ); + } + } + } + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java 2008/11/26 08:54:21 1.30 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java 2008/12/03 15:21:13 1.31 @@ -9,10 +9,10 @@ package org.biomoby.service.dashboard; /** - * A list of names of most/all recognized properties that can be fired by dashboard panels, and a list of names of Java - * properties that can be used to configure the dashboard. - *

- * + * A list of names of most/all recognized properties that can be fired + * by dashboard panels, and a list of names of Java properties that + * can be used to configure the dashboard.

+ * * @author Martin Senger * @version $Id$ */ @@ -44,9 +44,9 @@ static final String DP_FL_BIOCASE = "biocase"; static final String DP_FL_HIBERNATE = "hibernate"; - static final String DP_SEL_SERVICES = "selectedServices"; // type: Vector with service/authority name - static final String DP_SEL_AUTHORITIES = "selectedAuthorities"; // type: Vector with authority name - static final String DP_DEPL_SERVICES = "servicesToDeploy"; // type: Map with serviceName => className + static final String DP_SEL_SERVICES = "selectedServices"; // type: Vector with service/authority name + static final String DP_SEL_AUTHORITIES = "selectedAuthorities"; // type: Vector with authority name + static final String DP_DEPL_SERVICES = "servicesToDeploy"; // type: Map with serviceName => className static final String DP_LOCAL_DEPLOY = "use-local-deploy"; static final String DP_TOMCAT_HOME = "tomcatHome"; @@ -82,10 +82,10 @@ static final String DP_DETACH_VIEW = "detachViewers"; - // static final String DP_SC_IN_DATA = "sc-inputData"; +// static final String DP_SC_IN_DATA = "sc-inputData"; static final String DP_SC_IN_FILE = "sc-inputFromFile"; static final String DP_SC_INPUT_FILE = "sc-inputFile"; - static final String DP_SC_SERVICE = "dp-sc-service"; // type: MobyService + static final String DP_SC_SERVICE = "dp-sc-service"; // type: MobyService static final String DP_SC_SERVICE_NAME = "dp-sc-service-name"; static final String DP_SC_SERVICES = "dp-sc-recent-services"; @@ -97,21 +97,21 @@ static final String DP_DATATYPE_NAME = "dp-datatype-name"; // names of properties used in property channel storage - static final String DP_REGISTRY_MODEL = "dp-registry-model"; // type: RegistryModel - static final String DP_ANT_MODEL = "dp-ant-model"; // type: AntModel + static final String DP_REGISTRY_MODEL = "dp-registry-model"; // type: RegistryModel + static final String DP_ANT_MODEL = "dp-ant-model"; // type: AntModel static final String DP_REGISTRY_SYNONYM = "dp-registry-synonym"; - static final String DP_REG_INFO = "dp-reg-info"; // type: Boolean + static final String DP_REG_INFO = "dp-reg-info"; // type: Boolean static final String DP_REGISTRY_ENDPOINT = "dp-registry-endpoint"; static final String DP_REGISTRY_NAMESPACE = "dp-registry-namespace"; static final String DP_CACHE_DIR = "dp-cache-dir"; - static final String DP_USE_CACHE = "dp-use-cache"; // type: Boolean + static final String DP_USE_CACHE = "dp-use-cache"; // type: Boolean static final String DP_REG_DT_NAME = "dp-reg-dt-name"; static final String DP_REG_DT_AUTH = "dp-reg-dt-auth"; static final String DP_REG_DT_EMAIL = "dp-reg-dt-email"; static final String DP_REG_DT_DESC = "dp-reg-dt-desc"; - static final String DP_REG_DT_TREE = "dp-reg-dt-tree"; // type: MobyDataType + static final String DP_REG_DT_TREE = "dp-reg-dt-tree"; // type: MobyDataType static final String DP_REG_NS_NAME = "dp-reg-ns-name"; static final String DP_REG_NS_AUTH = "dp-reg-ns-auth"; @@ -132,88 +132,97 @@ static final String DP_REG_S_RDF_URL = "dp-reg-s-rdf-url"; static final String DP_REG_S_RDF_PATH = "dp-reg-s-rdf-path"; static final String DP_REG_S_XML_PATH = "dp-reg-s-xml-path"; - static final String DP_USE_SIGNATURE = "dp-use-signature"; // type: Boolean - static final String DP_USE_AUTHORITATIVE = "dp-use-auth"; // type: Boolean + static final String DP_USE_SIGNATURE = "dp-use-signature"; // type: Boolean + static final String DP_USE_AUTHORITATIVE = "dp-use-auth"; // type: Boolean static final String DP_REG_S_TYPE = "dp-reg-s-type"; static final String DP_REG_VERBOSE = "dp-reg-verbose"; - static final String DP_S_SELECTED = "dp-s-selected"; // type: MobyService + static final String DP_S_SELECTED = "dp-s-selected"; // type: MobyService - /** - * A property name. Its value contains a title that will appear in big fonts on top of the dashboard. It may be - * empty if property {@link #DP_TITLE_ICON} is defined; otherwise a default value will be used. + /** A property name. Its value contains a title that will appear + * in big fonts on top of the dashboard. It may be empty if + * property {@link #DP_TITLE_ICON} is defined; otherwise a default + * value will be used. */ static final String DP_TITLE = "dashboard.title"; - /** - * A property name. Its value contains a filename with an icon accompanying a dashboard title (defined by property - * {@link #DP_TITLE}. No default value used. Specify here either an absolute path (not recommended) or a relative - * path whose beginning can be found somewhere on the CLASSPATH. + /** A property name. Its value contains a filename with an icon + * accompanying a dashboard title (defined by property {@link + * #DP_TITLE}. No default value used. Specify here either an + * absolute path (not recommended) or a relative path whose + * beginning can be found somewhere on the CLASSPATH. */ static final String DP_TITLE_ICON = "dashboard.title.icon"; - /** - * A property name. Its value contains a filename with the main dashboard icon. Specify here either an absolute path - * (not recommended) or a relative path whose beginning can be found somewhere on the CLASSPATH. + /** A property name. Its value contains a filename with the main + * dashboard icon. Specify here either an absolute path (not + * recommended) or a relative path whose beginning can be found + * somewhere on the CLASSPATH. */ static final String DP_ICON = "dashboard.icon"; - /** - * A property name. Its value contains a color name used to paint main dashboard background. The name can be a color - * name, or a number in various format (see GraphColours for details). + /** A property name. Its value contains a color name used to paint + * main dashboard background. The name can be a color name, or a + * number in various format (see GraphColours for + * details). */ static final String DP_BGCOLOR = "dashboard.bgcolor"; - /** - * A property name. Its value contains a short description what a dashboard can do generally. Often, however, it is - * more convenient to put the description in a file and to use property {@link #DP_DESCRIPTION_FILE}. + /** A property name. Its value contains a short description what a + dashboard can do generally. Often, however, it is more + convenient to put the description in a file and to use + property {@link #DP_DESCRIPTION_FILE}. */ static final String DP_DESCRIPTION = "dashboard.description"; - /** - * A property name. Its value contains a file name with a short description what a dashboard can do generally. + /** A property name. Its value contains a file name with a short + description what a dashboard can do generally. */ static final String DP_DESCRIPTION_FILE = "dashboard.description.file"; - /** - * A property name. Its value contains a short description of a project that uses this dashboard. Often, however, it - * is more convenient to put the description in a file and to use property {@link #DP_P_DESCRIPTION_FILE}. + /** A property name. Its value contains a short description of a + project that uses this dashboard. Often, however, it is more + convenient to put the description in a file and to use + property {@link #DP_P_DESCRIPTION_FILE}. */ static final String DP_P_DESCRIPTION = "project.description"; - /** - * A property name. Its value contains a file name with a short description of a project that uses this dashboard. + /** A property name. Its value contains a file name with a short + description of a project that uses this dashboard. */ static final String DP_P_DESCRIPTION_FILE = "project.description.file"; - /** - * A property name. Its value contains a name of a contact person, possibly with an email address. + /** A property name. Its value contains a name of a contact + person, possibly with an email address. */ static final String DP_CONTACT = "dashboard.contact"; - /** - * A property name. Its value contains a directory name with the local cache of a BiMoby Central registry. + /** A property name. Its value contains a directory name with the + * local cache of a BiMoby Central registry. */ static final String DP_REGISTRY_CACHE_DIR = "registry.cache.dir"; - /** - * A property name. Its value contains a name or a comma-separated list of names of BioMoby registries that will be - * displayed in the RegistryPanel. If this property is missing, the list is taken from the hard-coded known - * registries in the Java source file. - *

- * - * The names (values of this property) are equivalent to the 'synonym' attribute of the Registry class. + /** A property name. Its value contains a name or a + * comma-separated list of names of BioMoby registries that will + * be displayed in the RegistryPanel. If this property is missing, + * the list is taken from the hard-coded known registries in the + * Java source file.

+ * + * The names (values of this property) are equivalent to the + * 'synonym' attribute of the Registry class. */ static final String DP_WANTED_REGISTRIES = "dashboard.wanted.registries"; - /** - * A property name. Its value contains a name (synonym) of a default BioMoby registry. By default, the default - * registry is taken either from the first element in {@link #DP_WANTED_REGISTRIES} or from + /** A property name. Its value contains a name (synonym) of a + * default BioMoby registry. By default, the default registry is + * taken either from the first element in {@link + * #DP_WANTED_REGISTRIES} or from * Registries.DEFAULT_REGISTRY_SYNONYM. */ static final String DP_DEFAULT_REGISTRY = "dashboard.default.registry"; + /** * A property name. Its value contains the user name used for the authentication required for the servlet container * the service is hosted at. From groscurt at dev.open-bio.org Wed Dec 3 10:21:13 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 10:21:13 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031521.mB3FLD8Y013747@dev.open-bio.org> groscurt Wed Dec 3 10:21:13 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv13676/src/main/org/biomoby/client Modified Files: MobyRequest.java BaseClient.java MobyServiceLocator.java Log Message: changes made for the authentication... without formatting this time moby-live/Java/src/main/org/biomoby/client MobyRequest.java,1.41,1.42 BaseClient.java,1.13,1.14 MobyServiceLocator.java,1.4,1.5 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java,v retrieving revision 1.41 retrieving revision 1.42 diff -u -r1.41 -r1.42 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java 2008/11/26 08:53:43 1.41 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java 2008/12/03 15:21:13 1.42 @@ -1,1028 +1,1030 @@ - -package org.biomoby.client; - -import java.io.*; -import java.util.*; - -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.rpc.Service; -import javax.xml.transform.TransformerException; - -import org.apache.axis.client.Call; -import org.apache.axis.message.MessageElement; -import org.apache.xml.utils.PrefixResolver; -import org.apache.xml.utils.PrefixResolverDefault; -import org.apache.xpath.XPath; -import org.apache.xpath.XPathContext; -import org.apache.xpath.objects.XNodeSet; -import org.apache.xpath.objects.XObject; - -import org.biomoby.shared.*; -import org.biomoby.shared.data.*; -import org.biomoby.shared.parser.MobyTags; // defined the Moby XML element names -import org.biomoby.w3c.addressing.EndpointReference; -import org.omg.lsae.notifications.AnalysisEvent; - -import org.w3c.dom.*; - -/** - * This class handles the WSDL transaction to request a response from a remote SOAP Web service that handles the MOBY format. It depends on having already retrieved the definition of the Web - * service via the MOBY central registry using the jMOBY - * API, and for now it uses the Apache Axis Web services framework, - * as well as Apache Xalan. There are code comments for the few lines that rely on Axis classes rather than the JAX-RPC - * interfaces. - * - * @author Paul Gordon gordonp at ucalgary.ca - */ -public class MobyRequest { - - protected MobyService mobyService = null; - protected MobyContentInstance inputData = null; - protected MobyContentInstance outputData = null; - protected Central mobyCentral = null; - protected PrefixResolver mobyPrefixResolver = null; - - protected Hashtable wsdlCache = null; - protected String lastWsdlCacheKey = null; - protected DocumentBuilder docBuilder = null; - protected Service service = null; - - protected Class stringType; - protected static boolean debug = false; - protected PrintStream debugPS = System.err; - protected XPathContext xpath_context; - protected String responseString = null; - - private XPath stringEncodedXPath; - private XPath base64EncodedXPath; - private XPath simpleChildXPath; - private XPath collectionChildXPath; - - private int autoID = 0; - - // Used as invocation callback if MobyRequest is acting as a server, - // or is executing services as a client asynchronously - private Vector< MobyRequestEventHandler > eventHandlers; - - private String user; - private String password; - - /** - * Default constructor. You should have a Central instance around since you're going to be retrieving MobyServices - * to pass into here. Lets reuse it. - * - * @param central An instance of a Moby central object so we can make requests about object types, etc. - * @throws ParserConfigurationException if JAXP doesn't have any valid DOM-building XML parsers set up for use - */ - public MobyRequest( Central central ) throws ParserConfigurationException { - mobyCentral = central; - wsdlCache = new Hashtable(); - - eventHandlers = new Vector< MobyRequestEventHandler >(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware( true ); - docBuilder = dbf.newDocumentBuilder(); - - try { - stringType = Class.forName( "java.lang.String" ); - } - catch ( ClassNotFoundException classe ) { - debugPS.println( "WARNING: Something is very wrong, could not find Class definition of String: " + classe ); - } - - xpath_context = new XPathContext(); - mobyPrefixResolver = new MobyPrefixResolver(); - - // Now compile the XPath statements that will be used fetch data from the server response - try { - base64EncodedXPath = new XPath( "//*[starts-with(substring-after(@" + MobyPrefixResolver.XSI1999_PREFIX - + ":type, ':'), \"base64\") or starts-with(substring-after(@" + MobyPrefixResolver.XSI2001_PREFIX - + ":type, ':'), \"base64\")]", null, mobyPrefixResolver, XPath.SELECT ); - stringEncodedXPath = new XPath( "//*[substring-after(@" + MobyPrefixResolver.XSI1999_PREFIX - + ":type, ':')=\"string\" or substring-after(@" + MobyPrefixResolver.XSI2001_PREFIX - + ":type, ':')=\"string\"] | //" + MobyPrefixResolver.SOAP_ENC_PREFIX + ":string", null, - mobyPrefixResolver, XPath.SELECT ); - simpleChildXPath = new XPath( "moby:Simple | Simple", null, mobyPrefixResolver, XPath.SELECT ); - collectionChildXPath = new XPath( "moby:Collection | Collection", null, mobyPrefixResolver, XPath.SELECT ); - } - catch ( TransformerException te ) { - debugPS.println( "Syntax error encountered while compiling XPath " - + "statements for internal use (code bug?): " + te ); - } - setDebugMode( System.getProperty( "moby.debug" ) != null ); - } - - /** - * @param mode if true, debugging information is printed to the stream returned by getDebugOutputStream - */ - public void setDebugMode(boolean mode) { - debug = mode; - } - - /** - * Standard error is used unless this method is called. - * - * @param ps the OutputStream to which debugging information is sent. - * @throws IllegalArgumentException if the stream is null - */ - public void setDebugPrintStream(PrintStream ps) throws IllegalArgumentException { - if ( ps == null ) { - throw new IllegalArgumentException( "The OutputStream specified to MobyRequest was null" ); - } - debugPS = ps; - } - - /** - * @param user the user for a possible service authentication - * @param password the passoword for a possible service authentication - */ - public void setAuthentication(String user, String password) { - this.user = user; - this.password = password; - } - - /** - * @return the instance of the class implementing Central that we are using - */ - public Central getCentralImpl() { - return mobyCentral; - } - - /** - * @param mobyservice the MobyService that should be executed when invokeService is called - */ - public void setService(MobyService mobyservice) { - if ( mobyservice == null ) { - mobyService = null; - } - else if ( mobyService == null || !mobyservice.equals( mobyService ) ) { - mobyService = mobyservice; - } - } - - /** - * @return the MobyService that will be executed when invokeService is called - */ - public MobyService getService() { - return mobyService; - } - - /** - * @return the Raw MOBY XML response as a string - */ - public String getResponseXML() { - return responseString; - } - - /** - * Sets the input data for the MOBY service request. The length of the input array, and the number of input - * parameters required by the service must be equal when invokeService() is called. This method strictly enforces - * that the input be of the appropriate type for the service. - * - * Note that there is no requirement to use MobyDataInstance.setXmlMode() before passing in data, this class will - * temporarily set the XML mode of the data when it is required. - * - * @throws IllegalArgumentException if the input does not fit the criteria of the service (e.g. wrong data type) - */ - public void setInput(MobyContentInstance data) throws MobyException { - inputData = data; - } - - /** - * Takes the data in the array, with their current articleNames, as input for the service - */ - public void setInput(MobyDataInstance[] data) throws MobyException { - MobyDataJob job = new MobyDataJob(); - for ( MobyDataInstance param : data ) { - job.put( param.getName(), param ); - } - inputData = new MobyContentInstance(); - inputData.put( job ); - } - - /** - * Convenience method to run services that take one argument. If the service requires the input to have a name, it - * will be automatically assigned. - */ - public void setInput(MobyDataInstance datum) throws MobyException { - setInput( datum, "" ); - } - - /** - * Convenience method to run services that take one named argument. - */ - public void setInput(MobyDataInstance datum, String paramName) throws MobyException { - inputData = new MobyContentInstance( datum, paramName ); - } - - /** - * @return the MobyService that will be executed when invokeService is called - */ - public MobyContentInstance getInput() { - return inputData; - } - - /** - * Same functionality as setSecondaryInput(MobyDataSecondaryInstance[]) - */ - public void setSecondaryInput(Collection< MobyDataSecondaryInstance > secondaryData) throws MobyException { - setSecondaryInput( secondaryData.toArray( new MobyDataSecondaryInstance[ secondaryData.size() ] ) ); - } - - /** - * This method will assign the provided secondary parameters to all primary input data currently in this object. - * This is covenient if you are running 100 seqs through BLAST and only want to set the parameters once. If you - * instead want to set secondary input differently for all primary inputs, you'll need to create a custom - * MobyContentInstance as input to setInput(). - * - * @throws MobyException if a parameter name is blank, or overrides a primary parameter - */ - public void setSecondaryInput(MobyDataSecondaryInstance[] secondaryData) throws MobyException { - - Iterator queryNames = inputData.keySet().iterator(); - // For each query - while (queryNames.hasNext()) { - MobyDataJob queryParams = inputData.get( queryNames.next() ); - // Set all the secondary params (overwrites any old ones) - for ( int i = 0; i < secondaryData.length; i++ ) { - String secName = secondaryData[ i ].getName(); - if ( secName == null || secName.length() == 0 ) { - throw new MobyException( "A secondary parameter cannot have a blank name (array index " + i + ")" ); - } - if ( queryParams.containsKey( secName ) && queryParams.get( secName ) instanceof MobyPrimaryData ) { - throw new MobyException( "A secondary parameter cannot override an existing primary parameter " - + "with the same name (" + secName + ")" ); - } - queryParams.put( secName, secondaryData[ i ] ); - } - } - } - - /** - * @return a vector of MobyDataInstance[], each element of the vector is the collection of response objects for the - * correspondingly indexed input request. - * - * @throws MobyException if you try to get the results before calling InvokeService - */ - public MobyContentInstance getOutput() throws MobyException { - if ( outputData == null ) { - throw new MobyException( "Trying to access MOBY service results " + "before the service is invoked" ); - } - else { - return outputData; - } - } - - /** - * The main method of the class. If all of the MOBY input objects are properly defined according to the Web service - * definition, a SOAP request will be sent to the remote server, and the method will return one or more MOBY objects - * (synchronous). Call this method after calling setService, and setInput. If you do not call setSecondaryInput, the - * default secondary parameter values will be used. - * - * @return the results of the remote Web service in response to the give input - * - * @throws MobyException i.e. there was something wrong with the input, output or remote service's logic - * @throws SOAPException i.e. there was a problem with the underlying transaction/transport layer - */ - public MobyContentInstance invokeService() throws Exception, MobyException, SOAPException, NoSuccessException { - return mobyService.isAsynchronous() - ? invokeService( inputData, new StringBuffer() ) - : invokeService( inputData, ( StringBuffer ) null ); - } - - // Used internally for asynchronous thread calls that all need the XML data - // and can't rely on the answer from thread-insensitive getResponseXML() - private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML) throws Exception, - MobyException, SOAPException, NoSuccessException { - return invokeService( inData, contentsXML, null, 0 ); - } - - private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML, - MobyRequestEventHandler handler, int requestId) throws Exception, MobyException, SOAPException, - NoSuccessException { - - if ( mobyService == null ) { - throw new MobyException( "Tried to invoke null service from MobyRequest (call setService first)" ); - } - - Element mobyDOM = null; - if ( mobyService.isAsynchronous() ) { - // Async is "simpler", because it had to merge DOMs together into a single MobyContentInstance anyway - MobyContentInstance mci = performAsyncSOAPRequest( mobyService, inData, handler, requestId ); - StringWriter writer = new StringWriter(); - MobyDataUtils.toXMLDocument( writer, mci ); - contentsXML.append( writer.toString() ); - return mci; - } - else { - String mobyXML = convertMOBYDataToMOBYRequest( inData ); - Call call = getServiceFromWSDL(); - if ( user != null && password != null ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, password ); - } - mobyDOM = performSOAPRequest( call, mobyXML, contentsXML ); - // The following parses the DOM and extracts all the appropriate jMOBY objects to represent the XML in Java - return MobyDataUtils.fromXMLDocument( mobyDOM, mobyService.getServiceType().getRegistry() ); - } - } - - protected MobyContentInstance performAsyncSOAPRequest(MobyService mservice, MobyContentInstance inData, - MobyRequestEventHandler handler, int requestId) throws Exception { - String mobyXML = convertMOBYDataToMOBYRequest( inData ); - EndpointReference epr = AsyncClient.sendRequest( mservice, mobyXML ); - - // Essentially cloning, so removing ids doesn't change the - // MobyContentInstance "data" (which we will use again later on) - MobyContentInstance finalContents = new MobyContentInstance(); - Set< String > queryIDs = new HashSet< String >( inData.keySet() ); - try { - // Should add some timeout here... - while (!queryIDs.isEmpty()) { - // todo: make this setable - Thread.sleep( 5000 ); - - AnalysisEvent[] events = AsyncClient.poll( epr, queryIDs ); - - Vector< String > newDataAvailable = new Vector< String >(); - for ( AnalysisEvent event : events ) { - if ( event != null && event.isCompleted() ) { - queryIDs.remove( event.getQueryId() ); - newDataAvailable.add( event.getQueryId() ); - } - } - - if ( newDataAvailable.size() > 0 ) { - // Parse and merge the new data into the existing contents - InputStream resultStream = AsyncClient.getResultStream( epr, newDataAvailable ); - Element mobyDOM = asyncSoapTextToMobyDOM( resultStream ); - MobyContentInstance newResults = MobyDataUtils.fromXMLDocument( mobyDOM, - mservice.getServiceType() - .getRegistry() ); - // The merge - for ( String jobid : newResults.keySet() ) { - finalContents.put( jobid, newResults.get( jobid ) ); - } - - // Inform the handler that some data has been added to the response (for incremental display?) - if ( handler != null ) { - MobyRequestEvent mre = new MobyRequestEvent( finalContents, this, mservice, null, requestId ); - StringWriter xmlWriter = new StringWriter(); - MobyDataUtils.toXMLDocument( xmlWriter, finalContents ); - - mre.setContentsXML( xmlWriter.toString() ); - if ( !queryIDs.isEmpty() ) { - // Send an update event only if we aren't finished yet. - // If we are finished, the client is going to get this event as the - // invocation thread finishes up (no need to double up). - handler.processEvent( mre ); - } - } - } - } - } - catch ( Exception e ) { - e.printStackTrace(); - AsyncClient.destroy( epr ); - throw new Exception( "Exception occured while polling the service invocation: " + e ); - } - - return finalContents; - } - - private Element asyncSoapTextToMobyDOM(InputStream inStream) throws Exception { - Element soapDOM = null; - synchronized ( docBuilder ) { - soapDOM = docBuilder.parse( inStream ).getDocumentElement(); - } - final boolean IS_ASYNC_SERVICE_CALL = true; - return decodeSOAPMessage( soapDOM, null, null, IS_ASYNC_SERVICE_CALL ); - } - - /** - * Asynchronous call to invokeService. A callback to the passed-in handler will be made when the response is ready, - * or there is an exception. - * - * @return the id that the callback event will return from getID(), allowing a client to distinguish between - * multiple concurrent invocation callbacks - */ - public synchronized int invokeService(MobyRequestEventHandler handler) { - int id = autoID++; - - Thread t = new InvocationThread( this, inputData, handler, id ); // see internal class definition below - t.start(); - - return id; - } - - // This is the class that asynchronously calls the service and does a callback to - // the handler specified in the invocation. - class InvocationThread extends Thread { - MobyContentInstance data; - MobyService mservice; - MobyRequest mobyRequest; - MobyRequestEventHandler handler; - int requestId; - - InvocationThread( MobyRequest mr, MobyContentInstance inData, MobyRequestEventHandler h, int id ) { - data = inData; - mobyRequest = mr; - mservice = mobyRequest.getService(); - handler = h; - requestId = id; - - // Name the thread after the service being run, mostly for ease of debugging - setName( mservice.getName() + requestId ); - } - - public void run() { - MobyRequestEvent requestEvent = new MobyRequestEvent( data, mobyRequest, mservice, null, requestId ); - // Tell the handler we're starting the request, with the given data - handler.start( requestEvent ); - - MobyRequestEvent responseEvent = null; - MobyContentInstance content = null; - StringBuffer contentsXML = new StringBuffer(); // to be filled in by the RPC call below - try { - content = mobyRequest.invokeService( data, contentsXML, handler, requestId ); // RPC call... - } - catch ( Exception e ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, e, requestId ); - } - catch ( Error err ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, err, requestId ); - } - if ( responseEvent == null ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, null, requestId ); - } - // We've got the raw XML laying around, so why not provide it unmolested to the callback? - responseEvent.setContentsXML( contentsXML.toString() ); - handler.processEvent( responseEvent ); - handler.stop( mobyRequest, requestId ); - } - } - - public void addEventHandler(MobyRequestEventHandler h) { - eventHandlers.add( h ); - } - - public void removeEventHandler(MobyRequestEventHandler h) { - eventHandlers.remove( h ); - } - - public void sendResponse(MobyRequestEvent mre) { - // Not yet implemented, need to conform to some web.xml specification here... - } - - /** - * This method retrieves from Moby Central a copy of the WSDL document for the service (or uses an internally cached - * copy from a previous invocation), and sets the variables for the SOAP call appropriately so you can consequently - * call performSOAPRequest. - */ - protected Call getServiceFromWSDL() throws MobyException, NoSuccessException { - // String wsdl = null; - - // // Since this is how we retrieve a service from Central, use the same values as the key to the hash - // String wsdlCacheKey = mobyService.getName() + "@" + mobyService.getAuthority(); - - // // This is the same call as last time, so we don't need to change the setup - // if(wsdlCacheKey.equals(lastWsdlCacheKey)){ - // return setCallFromWSDL((String) wsdlCache.get(wsdlCacheKey)); - // } - // // We haven't encountered this service yet - // else if(!wsdlCache.containsKey(wsdlCacheKey)){ - // wsdl = mobyCentral.getServiceWSDL(mobyService.getName(), mobyService.getAuthority()); - // wsdlCache.put(wsdlCacheKey, wsdl); - // } - // // We've dealt with this one before - // else{ - // wsdl = (String) wsdlCache.get(wsdlCacheKey); - // } - - // lastWsdlCacheKey = wsdlCacheKey; // Keep track of the last invocation - - // Get ready to do SOAP - return setCallFromWSDL( null ); - } - - /** - * Creates the SOAP Call that will be invoked later. This should be based on the WSDL document and parameter - * information from the MobyService, but these are currently not up to snuff. - */ - protected Call setCallFromWSDL(String wsdl) throws MobyException, SOAPException { - if ( service == null ) { - service = new org.apache.axis.client.Service(); // AXIS SPECIFIC This acts as a factory for Calls - } - - Call soapCall; - try { - soapCall = ( Call ) service.createCall();// create a fresh Call each time - } - catch ( javax.xml.rpc.ServiceException se ) { - throw new SOAPException( "Could not instatiate call to SOAP Service: " + se ); - } - - // Should initialize endpoint, etc. This call is AXIS SPECIFIC, otherwise you'll - // have to do the call's info setting manually. - // ((org.apache.axis.client.Call) soapCall).setSOAPService(soapService); - soapCall.removeAllParameters(); - soapCall.setTargetEndpointAddress( mobyService.getURL() ); - soapCall.setPortName( new QName( "http://biomoby.org/", mobyService.getName() + "PortType" ) ); - // soapCall.setOperationName(new QName("http://biomoby.org/", - // mobyService.getName())); - soapCall.setSOAPActionURI( "http://biomoby.org/#" + mobyService.getName() ); - return soapCall; - } - - /** - * Calls the invoke() method of the JAX-RPC Call interface. - */ - protected Element performSOAPRequest(Call soapCall, String mobyInputXML, StringBuffer contentsXMLOutput) - throws SOAPException { - // First, turn the input objects into a MOBY XML request - String[] mobyXMLInputData = new String[ 1 ]; - - // Setup - mobyXMLInputData[ 0 ] = mobyInputXML; - - if ( debug ) - debugPS.println( "returnType just before invoke call is " + soapCall.getReturnType() ); - Object returnedObject = null; - try { - returnedObject = soapCall.invoke( new QName( "http://biomoby.org/", mobyService.getName() ), - mobyXMLInputData ); - } - catch ( Exception e ) { - e.printStackTrace(); - // System.err.println("Input: "+mobyInputXML); - throw new SOAPException( "While invoking SOAP Call: " + e ); - } - - try { - if ( debug ) { - debugPS.println( "SOAP Response was:\n" ); - debugPS.println( soapCall.getResponseMessage().getSOAPPart().getEnvelope() ); - } - Element resultDom = ( ( MessageElement ) soapCall.getResponseMessage().getSOAPPart().getEnvelope() ).getAsDOM(); - return decodeSOAPMessage( resultDom, contentsXMLOutput, mobyInputXML ); - } - catch ( Exception e ) { - e.printStackTrace(); - throw new SOAPException( "Could not get SOAP response as DOM Element: " + e ); - } - - } - - public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML) throws SOAPException, - MobyException { - return decodeSOAPMessage( n, contentsXMLOutput, inputXML, false ); - } - - /** - * Isolates the MOBY Data from the SOAP message returned by the remote service host. - * - * @throws SOAPException if the MOBY payload cannot be found in the SOAP message - * @throws MobyException if the MOBY message is not well-formed XML - * - * @return The root element of the MOBY response DOM - */ - public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML, boolean async) - throws SOAPException, MobyException { - if ( n == null ) { - throw new SOAPException( "SOAP Message given to decode is null" ); - } - - NodeList node_list = null; - XPath responseElementXPath = null; - try { - if ( async ) { - responseElementXPath = new XPath( "//" + MobyPrefixResolver.WSRP_PREFIX + ":" - + AsyncClient.WSRP_MULTI_PROPERTY_TAG_NAME + "Response", null, mobyPrefixResolver, XPath.SELECT ); - } - else { - responseElementXPath = new XPath( "//" + MobyPrefixResolver.MOBY_TRANSPORT_PREFIX + ":" - + mobyService.getName() + "Response | //" + mobyService.getName() + "Response | " + "//" - + MobyPrefixResolver.MOBY_TRANSPORT_PREFIX + ":" + mobyService.getName() + " | //" - + mobyService.getName(), null, mobyPrefixResolver, XPath.SELECT ); - } - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select SOAP nodes due to exception " - + "while compiling XPath statement (code bug?):" + te ); - } - try { - node_list = runXPath( responseElementXPath, n ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select SOAP nodes due to exception " + "while executing XPath statement:" - + te ); - } - - if ( node_list == null || node_list.getLength() == 0 ) { - throw new SOAPException( "Could not find a response element in SOAP payload (service " - + mobyService.getName() + ")" ); - } - - if ( node_list.getLength() > 1 ) { - throw new SOAPException( "Found more than one response element in SOAP payload, " - + "unable to resolve ambiguity of the payload (service provider error?)" ); - } - - Node[] responseNodes = null; - if ( async ) { - Vector< Node > nodes = new Vector< Node >(); - NodeList resultNodeList = node_list.item( 0 ).getChildNodes(); - for ( int i = 0; resultNodeList != null && i < resultNodeList.getLength(); i++ ) { - if ( ! ( resultNodeList.item( i ) instanceof Element ) ) { - continue; - } - Element resultElement = ( Element ) resultNodeList.item( i ); - if ( resultElement.getLocalName().startsWith( AsyncClient.MOBY_RESULT_PROPERTY_PREFIX ) ) { - nodes.add( resultElement ); - } - } - responseNodes = nodes.toArray( new Node[ nodes.size() ] ); - } - else { - responseNodes = new Node[]{node_list.item( 0 )}; - } - - Element domRoot = null; // Where the result will be put - - for ( Node responseNode : responseNodes ) { - // Find base64 encoded elements in the SOAP message using XPath and - // replace them with the real decoded contents - node_list = null; - try { - node_list = runXPath( base64EncodedXPath, responseNode ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select base64 encoded SOAP nodes due to exception " - + "while executing XPath statement:" + te ); - } - if ( debug && node_list != null ) { - debugPS.println( "There were " + node_list.getLength() + " base64 encoded elements in the data" ); - } - - // Do decoding for each base64 part found - for ( int i = 0; node_list != null && i < node_list.getLength(); i++ ) { - org.w3c.dom.Node change = node_list.item( i ); - /* Make sure the text data is all put into one contiguous piece for decoding */ - change.normalize(); - - byte[] decodedBytes = org.apache.axis.encoding.Base64.decode( change.getFirstChild().getNodeValue() ); - String newText = new String( decodedBytes ); - if ( debug ) { - debugPS.println( "New decoded text is" + newText ); - } - - // Swap out this node for the decoded data - change.getParentNode().replaceChild( n.getOwnerDocument().createTextNode( new String( decodedBytes ) ), - change ); - } - - // Now see if there are any strings that need decoding - node_list = null; - try { - node_list = runXPath( stringEncodedXPath, responseNode ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select string encoded SOAP nodes due to exception " - + "while executing XPath statement:" + te ); - } - - // Do concatenation for each plain string part found - for ( int i = 0; node_list != null && i < node_list.getLength(); i++ ) { - org.w3c.dom.Node change = node_list.item( i ); - /* Make sure the text data is all put into one contiguous piece for decoding */ - change.normalize(); - String plainString = ""; - int j = 0; - for ( NodeList children = change.getChildNodes(); children != null && j < children.getLength(); j++ ) { - Node child = children.item( j ); - if ( child instanceof CDATASection || child instanceof Text ) { - plainString += child.getNodeValue(); - if ( debug ) { - debugPS.println( "Plain string is now " + plainString ); - } - } - } - - // Swap out this node for the decoded data - change.getParentNode().replaceChild( n.getOwnerDocument().createCDATASection( plainString ), change ); - } - if ( debug && node_list != null ) { - debugPS.println( "There were " + node_list.getLength() - + " XML Schema string encoded elements in the data" ); - } - - // Parse the MOBY XML document payload - responseNode.normalize(); - NodeList children = responseNode.getChildNodes(); - if ( children == null ) { - throw new MobyException( "The MOBY payload has no contents at all" ); - } - if ( children.getLength() != 1 ) { - if ( debug ) { - debugPS.println( "Warning: MOBY Payload appears to have more than " - + "just text in it, skipping the non-text sections" ); - } - } - - Element predefinedDOM = null; // Choice of ripping DOM Element for moby payload out of SOAP DOM - String localResponseString = ""; // or storing raw XML strings, to be converted to a DOM later - for ( int j = 0; j < children.getLength(); j++ ) { - Node child = children.item( j ); - if ( child instanceof CDATASection || child instanceof Text ) { - // Unescape XML special characters in the string, so we can later on - // parse the payload as regular XML. - // Ignore whitespace-only node - if ( child.getNodeValue().matches( "^\\s+$" ) ) { - continue; - } - if ( debug ) { - debugPS.println( "Concatenating text in response " + child.getNodeValue() ); - } - localResponseString += child.getNodeValue();// .replaceAll("<", "<").replaceAll(">", - // ">").replaceAll("(&|F)", "&"); - } - if ( child instanceof Element && child.getLocalName().equals( MobyTags.MOBY ) ) { - debugPS.println( "Warning: The MOBY contents was found as raw XML inside the SOAP response!\n" - + "This is illegal according to the MOBY-API, please inform the service\n " - + " provider, as parsing such text may not be supported in the future" ); - localResponseString = null; - // Store the moby payload root element's DOM represntation, so we don't - // have to serialize it to the localResponseString and then parse it out - // again (that would be wasteful). - predefinedDOM = ( Element ) child; - break; - } - } - - if ( localResponseString != null ) { - if ( localResponseString.length() == 0 ) { - throw new MobyException( "The MOBY payload has no text contents at all" ); - } - if ( Character.isWhitespace( localResponseString.charAt( 0 ) ) ) { - localResponseString = localResponseString.trim(); - } - } - - // Check if the payload is an XML document. If not, try a last ditch effort - // by base64 decoding the contents. This is technically not allowable in the - // MOBY spec, but we are being lenient. - if ( localResponseString != null && !localResponseString.startsWith( "\n" + localResponseString; - debugPS.println( "Warning: The MOBY contents was missing an XML declaration, but it is " - + "required by the MOBY API, and may stop working in the future without it. Please " - + "contact the client's provider to correct this." ); - } - else { - String oldResponse = localResponseString; - localResponseString = new String( org.apache.axis.encoding.Base64.decode( localResponseString ) ); - if ( !localResponseString.startsWith( " entry : data.entrySet() ) { - String queryName = entry.getKey(); - MobyDataJob query = entry.getValue(); - - // Additionally, we check if they are MobyDataInstances below - Map< String, MobyPrimaryData > primaryParams = new HashMap< String, MobyPrimaryData >(); - Map< String, MobySecondaryData > secondaryParams = new HashMap< String, MobySecondaryData >(); - - // To store the primary input parameter name as given by the user, - // in case we need it later on for parameter renaming... - String primaryParamName = null; - - for ( Map.Entry< String, MobyDataInstance > subentry : query.entrySet() ) { - String name = subentry.getKey(); - MobyDataInstance param = subentry.getValue(); - if ( param == null ) { - throw new MobyException( "Query " + queryName + " contained a null input parameter (" + name + ")" ); - } - else if ( param instanceof MobyPrimaryData ) { - primaryParams.put( name, ( MobyPrimaryData ) param ); - primaryParamName = name; - } - else if ( param instanceof MobySecondaryData ) { - secondaryParams.put( name, ( MobySecondaryData ) param ); - } - else { - System.err.println( "Input parameter " + name + " (query " + queryName - + ") was not a MobyPrimaryData or MobySecondaryData " - + "as expected, but rather was of class " + param.getClass().getName() ); - } - } - - if ( inputs != null && inputs.length != primaryParams.size() ) { - throw new MobyException( "Service " + mobyService.getName() + " was provided " + primaryParams.size() - + " primary input parameter(s), but takes " + inputs.length + " (query " + queryName + ")" ); - } - if ( secondaries != null ) { - // If no secondaries provided, fill them in by default - if ( secondaries.length != 0 ) { - for ( MobySecondaryData secondary : secondaries ) { - if ( !secondaryParams.containsKey( secondary.getName() ) ) { - if ( debug ) { - System.err.println( "Setting default secondary param value for missing param " - + secondary ); - } - query.put( secondary.getName(), new MobyDataSecondaryInstance( secondary ) ); - } - } - } - if ( secondaries.length != secondaryParams.size() ) { - throw new MobyException( "Service " + mobyService.getName() + " was provided " - + secondaryParams.size() + " secondary input parameter(s), but takes " + secondaries.length - + " (query " + queryName + "). Extra secondary" + " parameters must have been specified" ); - } - } - - // If there was one anonymous input, assign the name automatically in - // the case the service requires it to be named. This is the only - // unambiguous case in which we can do this. - if ( inputs.length == 1 ) { - String serviceParamName = inputs[ 0 ].getName(); // name as req'd by the service - - // name isn't the same as required currently - if ( serviceParamName != null && serviceParamName.length() > 0 - && !serviceParamName.equals( primaryParamName ) ) { - // take out the old parameter - MobyPrimaryData theInputToRename = ( MobyPrimaryData ) query.remove( primaryParamName ); - - // Add in the same parameter, but with the appropriate name - query.put( serviceParamName, ( MobyDataInstance ) theInputToRename ); - } - } - } - - ByteArrayOutputStream mobyRequest = new ByteArrayOutputStream(); - try { - MobyDataUtils.toXMLDocument( mobyRequest, data ); - } - catch ( MobyException me ) { - throw me; - } - catch ( Exception e ) { - e.printStackTrace(); - throw new MobyException( "Could not create MOBY payload XML from input data: " + e ); - } - - if ( debug ) { - debugPS.println( "Input to MOBY Service is:" ); - debugPS.print( mobyRequest.toString() ); - } - - return mobyRequest.toString(); - } - - /** - * A method that sets up the execution environment for and runs a compiled XPath statement against a DOM node You - * should call releaseXPath when you're done with the results - * - * @return the list of Nodes that satisfy the XPath in this Node's context - */ - protected NodeList runXPath(XPath xpath, Node n) throws TransformerException { - NodeList result = null; - int dtm_node_handle = xpath_context.getDTMHandleFromNode( n ); - PrefixResolver node_prefix_resolver = new PrefixResolverDefault( n ); - XObject xobject = xpath.execute( xpath_context, n, node_prefix_resolver ); - if ( xobject instanceof XNodeSet ) { - result = ( ( XNodeSet ) xobject ).nodelist(); - } - else if ( debug && xobject != null ) { - debugPS.println( "Output of XPath was not a XNodeSet as expected, found " + xobject.getClass().getName() ); - debugPS.flush(); - } - return result; - } - - protected void releaseXPath(Node n) { - xpath_context.release( xpath_context.getDTM( xpath_context.getDTMHandleFromNode( n ) ), false ); - } -} +package org.biomoby.client; + +import java.io.*; +import java.util.*; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.rpc.Service; +import javax.xml.transform.TransformerException; + +import org.apache.axis.client.Call; +import org.apache.axis.message.MessageElement; +import org.apache.xml.utils.PrefixResolver; +import org.apache.xml.utils.PrefixResolverDefault; +import org.apache.xpath.XPath; +import org.apache.xpath.XPathContext; +import org.apache.xpath.objects.XNodeSet; +import org.apache.xpath.objects.XObject; + +import org.biomoby.shared.*; +import org.biomoby.shared.data.*; +import org.biomoby.shared.parser.MobyTags; // defined the Moby XML element names +import org.biomoby.w3c.addressing.EndpointReference; +import org.omg.lsae.notifications.AnalysisEvent; + +import org.w3c.dom.*; + +/** + * This class handles the WSDL transaction to request a response + * from a remote SOAP Web service that handles the + * MOBY format. It depends on + * having already retrieved the definition of the Web service via + * the MOBY central registry using the + * jMOBY API, + * and for now it uses the + * Apache + * Axis Web services framework, as well as Apache Xalan. There are code comments for the + * few lines that rely on Axis classes rather than the JAX-RPC interfaces. + * + * @author Paul Gordon gordonp at ucalgary.ca + */ +public class MobyRequest{ + + protected MobyService mobyService = null; + protected MobyContentInstance inputData = null; + protected MobyContentInstance outputData = null; + protected Central mobyCentral = null; + protected PrefixResolver mobyPrefixResolver = null; + + protected Hashtable wsdlCache = null; + protected String lastWsdlCacheKey = null; + protected DocumentBuilder docBuilder = null; + protected Service service = null; + + protected Class stringType; + protected static boolean debug = false; + protected PrintStream debugPS = System.err; + protected XPathContext xpath_context; + protected String responseString = null; + + private XPath stringEncodedXPath; + private XPath base64EncodedXPath; + private XPath simpleChildXPath; + private XPath collectionChildXPath; + private String user; + private String password; + + private int autoID = 0; + + // Used as invocation callback if MobyRequest is acting as a server, + // or is executing services as a client asynchronously + private Vector eventHandlers; + + /** + * Default constructor. You should have a Central instance around since you're going to + * be retrieving MobyServices to pass into here. Lets reuse it. + * + * @param central An instance of a Moby central object so we can make requests about object types, etc. + * @throws ParserConfigurationException if JAXP doesn't have any valid DOM-building XML parsers set up for use + */ + public MobyRequest(Central central) throws ParserConfigurationException{ + mobyCentral = central; + wsdlCache = new Hashtable(); + + eventHandlers = new Vector(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + docBuilder = dbf.newDocumentBuilder(); + + try{ + stringType = Class.forName("java.lang.String"); + }catch(ClassNotFoundException classe){ + debugPS.println("WARNING: Something is very wrong, could not find Class definition of String: " + classe); + } + + xpath_context = new XPathContext(); + mobyPrefixResolver = new MobyPrefixResolver(); + + // Now compile the XPath statements that will be used fetch data from the server response + try{ + base64EncodedXPath = new XPath("//*[starts-with(substring-after(@"+ + MobyPrefixResolver.XSI1999_PREFIX+ + ":type, ':'), \"base64\") or starts-with(substring-after(@"+ + MobyPrefixResolver.XSI2001_PREFIX+ + ":type, ':'), \"base64\")]", null, + mobyPrefixResolver, XPath.SELECT); + stringEncodedXPath = new XPath("//*[substring-after(@"+ + MobyPrefixResolver.XSI1999_PREFIX+ + ":type, ':')=\"string\" or substring-after(@"+ + MobyPrefixResolver.XSI2001_PREFIX+ + ":type, ':')=\"string\"] | //"+ + MobyPrefixResolver.SOAP_ENC_PREFIX+":string", null, + mobyPrefixResolver, XPath.SELECT); + simpleChildXPath = new XPath("moby:Simple | Simple", null, + mobyPrefixResolver, XPath.SELECT); + collectionChildXPath = new XPath("moby:Collection | Collection", null, + mobyPrefixResolver, XPath.SELECT); + } + catch(TransformerException te){ + debugPS.println("Syntax error encountered while compiling XPath " + + "statements for internal use (code bug?): " + te); + } + setDebugMode(System.getProperty("moby.debug") != null); + } + + public void setAuthentication(String user, String password){ + this.user = user; + this.password = password; + } + + /** + * @param mode if true, debugging information is printed to the stream returned by getDebugOutputStream + */ + public void setDebugMode(boolean mode){ + debug = mode; + } + + /** + * Standard error is used unless this method is called. + * + * @param ps the OutputStream to which debugging information is sent. + * @throws IllegalArgumentException if the stream is null + */ + public void setDebugPrintStream(PrintStream ps) throws IllegalArgumentException{ + if(ps == null){ + throw new IllegalArgumentException("The OutputStream specified to MobyRequest was null"); + } + debugPS = ps; + } + + /** + * @return the instance of the class implementing Central that we are using + */ + public Central getCentralImpl(){ + return mobyCentral; + } + + /** + * @param mobyservice the MobyService that should be executed when invokeService is called + */ + public void setService(MobyService mobyservice){ + if(mobyservice == null){ + mobyService = null; + } + else if(mobyService == null || !mobyservice.equals(mobyService)){ + mobyService = mobyservice; + } + } + + /** + * @return the MobyService that will be executed when invokeService is called + */ + public MobyService getService(){ + return mobyService; + } + + /** + * @return the Raw MOBY XML response as a string + */ + public String getResponseXML(){ + return responseString; + } + + /** + * Sets the input data for the MOBY service request. The length of the input array, and the + * number of input parameters required by the service must be equal when invokeService() is called. + * This method strictly enforces that the input be of the appropriate type for the service. + * + * Note that there is no requirement to use MobyDataInstance.setXmlMode() before passing in + * data, this class will temporarily set the XML mode of the data when it is required. + * + * @throws IllegalArgumentException if the input does not fit the criteria of the service (e.g. wrong data type) + */ + public void setInput(MobyContentInstance data) throws MobyException{ + inputData = data; + } + + /** + * Takes the data in the array, with their current articleNames, as input for the service + */ + public void setInput(MobyDataInstance[] data) throws MobyException{ + MobyDataJob job = new MobyDataJob(); + for(MobyDataInstance param: data){ + job.put(param.getName(), param); + } + inputData = new MobyContentInstance(); + inputData.put(job); + } + + /** + * Convenience method to run services that take one argument. If the service + * requires the input to have a name, it will be automatically assigned. + */ + public void setInput(MobyDataInstance datum) throws MobyException{ + setInput(datum, ""); + } + + /** + * Convenience method to run services that take one named argument. + */ + public void setInput(MobyDataInstance datum, String paramName) throws MobyException{ + inputData = new MobyContentInstance(datum, paramName); + } + + /** + * @return the MobyService that will be executed when invokeService is called + */ + public MobyContentInstance getInput(){ + return inputData; + } + + /** + * Same functionality as setSecondaryInput(MobyDataSecondaryInstance[]) + */ + public void setSecondaryInput(Collection secondaryData) throws MobyException{ + setSecondaryInput(secondaryData.toArray(new MobyDataSecondaryInstance[secondaryData.size()])); + } + + /** + * This method will assign the provided secondary parameters to all primary input data currently + * in this object. This is covenient if you are running 100 seqs through BLAST and only want to set + * the parameters once. If you instead want to set secondary input differently for all primary inputs, you'll + * need to create a custom MobyContentInstance as input to setInput(). + * + * @throws MobyException if a parameter name is blank, or overrides a primary parameter + */ + public void setSecondaryInput(MobyDataSecondaryInstance[] secondaryData) throws MobyException{ + + Iterator queryNames = inputData.keySet().iterator(); + // For each query + while(queryNames.hasNext()){ + MobyDataJob queryParams = inputData.get(queryNames.next()); + // Set all the secondary params (overwrites any old ones) + for(int i = 0; i < secondaryData.length; i++){ + String secName = secondaryData[i].getName(); + if(secName == null || secName.length() == 0){ + throw new MobyException("A secondary parameter cannot have a blank name (array index " + i + ")"); + } + if(queryParams.containsKey(secName) && queryParams.get(secName) instanceof MobyPrimaryData){ + throw new MobyException("A secondary parameter cannot override an existing primary parameter " + + "with the same name (" + secName + ")"); + } + queryParams.put(secName, secondaryData[i]); + } + } + } + + /** + * @return a vector of MobyDataInstance[], each element of the vector is the collection of response objects for the correspondingly indexed input request. + * + * @throws MobyException if you try to get the results before calling InvokeService + */ + public MobyContentInstance getOutput() throws MobyException{ + if(outputData == null){ + throw new MobyException("Trying to access MOBY service results " + + "before the service is invoked"); + } + else{ + return outputData; + } + } + + /** + * The main method of the class. If all of the MOBY input objects + * are properly defined according to the Web service definition, + * a SOAP request will be sent to the remote server, and the method + * will return one or more MOBY objects (synchronous). + * Call this method after calling setService, and setInput. If you do not call + * setSecondaryInput, the default secondary parameter values will be used. + * + * @return the results of the remote Web service in response to the give input + * + * @throws MobyException i.e. there was something wrong with the input, output or remote service's logic + * @throws SOAPException i.e. there was a problem with the underlying transaction/transport layer + */ + public MobyContentInstance invokeService() throws Exception, MobyException, SOAPException, NoSuccessException{ + return mobyService.isAsynchronous() ? invokeService(inputData, new StringBuffer()) : invokeService(inputData, (StringBuffer) null); + } + + // Used internally for asynchronous thread calls that all need the XML data + // and can't rely on the answer from thread-insensitive getResponseXML() + private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML) + throws Exception, MobyException, SOAPException, NoSuccessException{ + return invokeService(inData, contentsXML, null, 0); + } + + private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML, MobyRequestEventHandler handler, int requestId) + throws Exception, MobyException, SOAPException, NoSuccessException{ + + if(mobyService == null){ + throw new MobyException("Tried to invoke null service from MobyRequest (call setService first)"); + } + + Element mobyDOM = null; + if(mobyService.isAsynchronous()){ + // Async is "simpler", because it had to merge DOMs together into a single MobyContentInstance anyway + MobyContentInstance mci = performAsyncSOAPRequest(mobyService, inData, handler, requestId); + StringWriter writer = new StringWriter(); + MobyDataUtils.toXMLDocument(writer, mci); + contentsXML.append(writer.toString()); + return mci; + } + else{ + String mobyXML = convertMOBYDataToMOBYRequest(inData); + Call call = getServiceFromWSDL(); + if(user != null && password != null) { + call.setProperty( Call.USERNAME_PROPERTY, user ); + call.setProperty( Call.PASSWORD_PROPERTY, password ); + } + mobyDOM = performSOAPRequest(call, mobyXML, contentsXML); + // The following parses the DOM and extracts all the appropriate jMOBY objects to represent the XML in Java + return MobyDataUtils.fromXMLDocument(mobyDOM, mobyService.getServiceType().getRegistry()); + } + } + + protected MobyContentInstance performAsyncSOAPRequest(MobyService mservice, MobyContentInstance inData, + MobyRequestEventHandler handler, int requestId) + throws Exception{ + String mobyXML = convertMOBYDataToMOBYRequest(inData); + EndpointReference epr = AsyncClient.sendRequest(mservice, mobyXML); + + // Essentially cloning, so removing ids doesn't change the + // MobyContentInstance "data" (which we will use again later on) + MobyContentInstance finalContents = new MobyContentInstance(); + Set queryIDs = new HashSet(inData.keySet()); + try { + // Should add some timeout here... + while(!queryIDs.isEmpty()){ + // todo: make this setable + Thread.sleep(5000); + + AnalysisEvent[] events = + AsyncClient.poll(epr, queryIDs); + + Vector newDataAvailable = new Vector(); + for(AnalysisEvent event: events){ + if(event != null && event.isCompleted()){ + queryIDs.remove(event.getQueryId()); + newDataAvailable.add(event.getQueryId()); + } + } + + if(newDataAvailable.size() > 0){ + // Parse and merge the new data into the existing contents + InputStream resultStream = AsyncClient.getResultStream(epr, newDataAvailable); + Element mobyDOM = asyncSoapTextToMobyDOM(resultStream); + MobyContentInstance newResults = MobyDataUtils.fromXMLDocument(mobyDOM, mservice.getServiceType().getRegistry()); + // The merge + for(String jobid: newResults.keySet()){ + finalContents.put(jobid, newResults.get(jobid)); + } + + // Inform the handler that some data has been added to the response (for incremental display?) + if(handler != null){ + MobyRequestEvent mre = new MobyRequestEvent(finalContents, this, mservice, null, requestId); + StringWriter xmlWriter = new StringWriter(); + MobyDataUtils.toXMLDocument(xmlWriter, finalContents); + + mre.setContentsXML(xmlWriter.toString()); + if(!queryIDs.isEmpty()){ + // Send an update event only if we aren't finished yet. + // If we are finished, the client is going to get this event as the + // invocation thread finishes up (no need to double up). + handler.processEvent(mre); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + AsyncClient.destroy(epr); + throw new Exception("Exception occured while polling the service invocation: " + e); + } + + return finalContents; + } + + private Element asyncSoapTextToMobyDOM(InputStream inStream) throws Exception{ + Element soapDOM = null; + synchronized(docBuilder){ + soapDOM = docBuilder.parse(inStream).getDocumentElement(); + } + final boolean IS_ASYNC_SERVICE_CALL = true; + return decodeSOAPMessage(soapDOM, null, null, IS_ASYNC_SERVICE_CALL); + } + + /** + * Asynchronous call to invokeService. A callback to the passed-in handler will be made when + * the response is ready, or there is an exception. + * + * @return the id that the callback event will return from getID(), allowing a client to distinguish between multiple concurrent invocation callbacks + */ + public synchronized int invokeService(MobyRequestEventHandler handler){ + int id = autoID++; + + Thread t = new InvocationThread(this, inputData, handler, id); // see internal class definition below + t.start(); + + return id; + } + + // This is the class that asynchronously calls the service and does a callback to + // the handler specified in the invocation. + class InvocationThread extends Thread { + MobyContentInstance data; + MobyService mservice; + MobyRequest mobyRequest; + MobyRequestEventHandler handler; + int requestId; + + InvocationThread(MobyRequest mr, MobyContentInstance inData, MobyRequestEventHandler h, int id){ + data = inData; + mobyRequest = mr; + mservice = mobyRequest.getService(); + handler = h; + requestId = id; + + // Name the thread after the service being run, mostly for ease of debugging + setName(mservice.getName()+requestId); + } + + public void run() { + MobyRequestEvent requestEvent = new MobyRequestEvent(data, mobyRequest, mservice, null, requestId); + // Tell the handler we're starting the request, with the given data + handler.start(requestEvent); + + MobyRequestEvent responseEvent = null; + MobyContentInstance content = null; + StringBuffer contentsXML = new StringBuffer(); //to be filled in by the RPC call below + try{ + content = mobyRequest.invokeService(data, contentsXML, handler, requestId); //RPC call... + } + catch(Exception e){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, e, requestId); + } + catch(Error err){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, err, requestId); + } + if(responseEvent == null){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, null, requestId); + } + // We've got the raw XML laying around, so why not provide it unmolested to the callback? + responseEvent.setContentsXML(contentsXML.toString()); + handler.processEvent(responseEvent); + handler.stop(mobyRequest, requestId); + } + } + + public void addEventHandler(MobyRequestEventHandler h){ + eventHandlers.add(h); + } + + public void removeEventHandler(MobyRequestEventHandler h){ + eventHandlers.remove(h); + } + + public void sendResponse(MobyRequestEvent mre){ + // Not yet implemented, need to conform to some web.xml specification here... + } + + /** + * This method retrieves from Moby Central a copy of the WSDL document for the service + * (or uses an internally cached copy from a previous invocation), and sets the variables for the + * SOAP call appropriately so you can consequently call performSOAPRequest. + */ + protected Call getServiceFromWSDL() throws MobyException, NoSuccessException{ +// String wsdl = null; + +// // Since this is how we retrieve a service from Central, use the same values as the key to the hash +// String wsdlCacheKey = mobyService.getName() + "@" + mobyService.getAuthority(); + +// // This is the same call as last time, so we don't need to change the setup +// if(wsdlCacheKey.equals(lastWsdlCacheKey)){ +// return setCallFromWSDL((String) wsdlCache.get(wsdlCacheKey)); +// } +// // We haven't encountered this service yet +// else if(!wsdlCache.containsKey(wsdlCacheKey)){ +// wsdl = mobyCentral.getServiceWSDL(mobyService.getName(), mobyService.getAuthority()); +// wsdlCache.put(wsdlCacheKey, wsdl); +// } +// // We've dealt with this one before +// else{ +// wsdl = (String) wsdlCache.get(wsdlCacheKey); +// } + +// lastWsdlCacheKey = wsdlCacheKey; // Keep track of the last invocation + + // Get ready to do SOAP + return setCallFromWSDL(null); + } + + /** + * Creates the SOAP Call that will be invoked later. This should be based on the WSDL document + * and parameter information from the MobyService, but these are currently not up to snuff. + */ + protected Call setCallFromWSDL(String wsdl) throws MobyException, SOAPException{ + if(service == null){ + service = new org.apache.axis.client.Service(); // AXIS SPECIFIC This acts as a factory for Calls + } + + Call soapCall; + try{ + soapCall = (Call) service.createCall();//create a fresh Call each time + }catch(javax.xml.rpc.ServiceException se){ + throw new SOAPException("Could not instatiate call to SOAP Service: " + se); + } + + // Should initialize endpoint, etc. This call is AXIS SPECIFIC, otherwise you'll + // have to do the call's info setting manually. + //((org.apache.axis.client.Call) soapCall).setSOAPService(soapService); + soapCall.removeAllParameters(); + soapCall.setTargetEndpointAddress(mobyService.getURL()); + soapCall.setPortName(new QName("http://biomoby.org/", + mobyService.getName() + "PortType")); + //soapCall.setOperationName(new QName("http://biomoby.org/", + // mobyService.getName())); + soapCall.setSOAPActionURI("http://biomoby.org/#" + mobyService.getName()); + return soapCall; + } + + /** + * Calls the invoke() method of the JAX-RPC Call interface. + */ + protected Element performSOAPRequest(Call soapCall, String mobyInputXML, StringBuffer contentsXMLOutput) throws SOAPException{ + // First, turn the input objects into a MOBY XML request + String[] mobyXMLInputData = new String[1]; + + //Setup + mobyXMLInputData[0] = mobyInputXML; + + if(debug) + debugPS.println("returnType just before invoke call is " + soapCall.getReturnType()); + Object returnedObject = null; + try{ + returnedObject = soapCall.invoke(new QName("http://biomoby.org/", + mobyService.getName()), mobyXMLInputData); + } + catch(Exception e){ + e.printStackTrace(); + //System.err.println("Input: "+mobyInputXML); + throw new SOAPException("While invoking SOAP Call: " + e); + } + + try{ + if(debug){ + debugPS.println("SOAP Response was:\n"); + debugPS.println(soapCall.getResponseMessage().getSOAPPart().getEnvelope()); + } + Element resultDom = ((MessageElement) soapCall.getResponseMessage().getSOAPPart().getEnvelope()).getAsDOM(); + return decodeSOAPMessage(resultDom, contentsXMLOutput, mobyInputXML); + } catch(Exception e){ + e.printStackTrace(); + throw new SOAPException("Could not get SOAP response as DOM Element: "+ e); + } + + } + + public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML) + throws SOAPException, MobyException{ + return decodeSOAPMessage(n, contentsXMLOutput, inputXML, false); + } + + /** + * Isolates the MOBY Data from the SOAP message returned by the remote service host. + * + * @throws SOAPException if the MOBY payload cannot be found in the SOAP message + * @throws MobyException if the MOBY message is not well-formed XML + * + * @return The root element of the MOBY response DOM + */ + public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML, boolean async) + throws SOAPException, MobyException{ + if(n == null){ + throw new SOAPException("SOAP Message given to decode is null"); + } + + NodeList node_list = null; + XPath responseElementXPath = null; + try{ + if(async){ + responseElementXPath = new XPath("//"+MobyPrefixResolver.WSRP_PREFIX + + ":"+AsyncClient.WSRP_MULTI_PROPERTY_TAG_NAME+"Response", + null, mobyPrefixResolver, XPath.SELECT); + } + else{ + responseElementXPath = new XPath("//"+ MobyPrefixResolver.MOBY_TRANSPORT_PREFIX+ + ":"+mobyService.getName()+"Response | //" + + mobyService.getName()+"Response | " + + "//"+ MobyPrefixResolver.MOBY_TRANSPORT_PREFIX+ + ":"+mobyService.getName() + " | //" + + mobyService.getName(), + null, mobyPrefixResolver, XPath.SELECT); + } + }catch(TransformerException te){ + throw new SOAPException("Cannot select SOAP nodes due to exception "+ + "while compiling XPath statement (code bug?):" +te); + } + try{ + node_list = runXPath(responseElementXPath, n); + }catch(TransformerException te){ + throw new SOAPException("Cannot select SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + + if(node_list == null || node_list.getLength() == 0){ + throw new SOAPException("Could not find a response element in SOAP payload (service " + + mobyService.getName() + ")"); + } + + if(node_list.getLength() > 1){ + throw new SOAPException("Found more than one response element in SOAP payload, " + + "unable to resolve ambiguity of the payload (service provider error?)"); + } + + Node[] responseNodes = null; + if(async){ + Vector nodes = new Vector(); + NodeList resultNodeList = node_list.item(0).getChildNodes(); + for(int i = 0; resultNodeList != null && i < resultNodeList.getLength(); i++){ + if(!(resultNodeList.item(i) instanceof Element)){ + continue; + } + Element resultElement = (Element) resultNodeList.item(i); + if(resultElement.getLocalName().startsWith(AsyncClient.MOBY_RESULT_PROPERTY_PREFIX)){ + nodes.add(resultElement); + } + } + responseNodes = nodes.toArray(new Node[nodes.size()]); + } + else{ + responseNodes = new Node[]{node_list.item(0)}; + } + + Element domRoot = null; // Where the result will be put + + for(Node responseNode: responseNodes){ + // Find base64 encoded elements in the SOAP message using XPath and + // replace them with the real decoded contents + node_list = null; + try{ + node_list = runXPath(base64EncodedXPath, responseNode); + } + catch(TransformerException te){ + throw new SOAPException("Cannot select base64 encoded SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + if(debug && node_list != null){ + debugPS.println("There were " + node_list.getLength() + + " base64 encoded elements in the data"); + } + + // Do decoding for each base64 part found + for(int i = 0; node_list != null && i < node_list.getLength(); i++){ + org.w3c.dom.Node change = node_list.item(i); + /* Make sure the text data is all put into one contiguous piece for decoding*/ + change.normalize(); + + byte[] decodedBytes = org.apache.axis.encoding.Base64.decode(change.getFirstChild().getNodeValue()); + String newText = new String(decodedBytes); + if(debug){ + debugPS.println("New decoded text is" + newText); + } + + // Swap out this node for the decoded data + change.getParentNode().replaceChild(n.getOwnerDocument().createTextNode(new String(decodedBytes)), + change); + } + + // Now see if there are any strings that need decoding + node_list = null; + try{ + node_list = runXPath(stringEncodedXPath, responseNode); + } + catch(TransformerException te){ + throw new SOAPException("Cannot select string encoded SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + + // Do concatenation for each plain string part found + for(int i = 0; node_list != null && i < node_list.getLength(); i++){ + org.w3c.dom.Node change = node_list.item(i); + /* Make sure the text data is all put into one contiguous piece for decoding*/ + change.normalize(); + String plainString = ""; + int j = 0; + for(NodeList children = change.getChildNodes(); + children != null && j < children.getLength(); + j++){ + Node child = children.item(j); + if(child instanceof CDATASection || child instanceof Text){ + plainString += child.getNodeValue(); + if(debug){ + debugPS.println("Plain string is now " + plainString); + } + } + } + + // Swap out this node for the decoded data + change.getParentNode().replaceChild(n.getOwnerDocument().createCDATASection(plainString), change); + } + if(debug && node_list != null){ + debugPS.println("There were " + node_list.getLength() + + " XML Schema string encoded elements in the data"); + } + + // Parse the MOBY XML document payload + responseNode.normalize(); + NodeList children = responseNode.getChildNodes(); + if(children == null){ + throw new MobyException("The MOBY payload has no contents at all"); + } + if(children.getLength() != 1){ + if(debug){ + debugPS.println("Warning: MOBY Payload appears to have more than " + + "just text in it, skipping the non-text sections"); + } + } + + Element predefinedDOM = null; // Choice of ripping DOM Element for moby payload out of SOAP DOM + String localResponseString = ""; // or storing raw XML strings, to be converted to a DOM later + for(int j = 0; j < children.getLength(); j++){ + Node child = children.item(j); + if(child instanceof CDATASection || child instanceof Text){ + // Unescape XML special characters in the string, so we can later on + // parse the payload as regular XML. + // Ignore whitespace-only node + if(child.getNodeValue().matches("^\\s+$")){ + continue; + } + if(debug){ + debugPS.println("Concatenating text in response " + child.getNodeValue()); + } + localResponseString += child.getNodeValue();//.replaceAll("<", "<").replaceAll(">", ">").replaceAll("(&|F)", "&"); + } + if(child instanceof Element && child.getLocalName().equals(MobyTags.MOBY)){ + debugPS.println("Warning: The MOBY contents was found as raw XML inside the SOAP response!\n" + + "This is illegal according to the MOBY-API, please inform the service\n " + + " provider, as parsing such text may not be supported in the future"); + localResponseString = null; + // Store the moby payload root element's DOM represntation, so we don't + // have to serialize it to the localResponseString and then parse it out + // again (that would be wasteful). + predefinedDOM = (Element) child; + break; + } + } + + if(localResponseString != null){ + if(localResponseString.length() == 0){ + throw new MobyException("The MOBY payload has no text contents at all"); + } + if(Character.isWhitespace(localResponseString.charAt(0))){ + localResponseString = localResponseString.trim(); + } + } + + // Check if the payload is an XML document. If not, try a last ditch effort + // by base64 decoding the contents. This is technically not allowable in the + // MOBY spec, but we are being lenient. + if(localResponseString != null && !localResponseString.startsWith("\n"+localResponseString; + debugPS.println("Warning: The MOBY contents was missing an XML declaration, but it is " + + "required by the MOBY API, and may stop working in the future without it. Please " + + "contact the client's provider to correct this."); + } + else{ + String oldResponse = localResponseString; + localResponseString = new String(org.apache.axis.encoding.Base64.decode(localResponseString)); + if(!localResponseString.startsWith(" entry: data.entrySet()){ + String queryName = entry.getKey(); + MobyDataJob query = entry.getValue(); + + // Additionally, we check if they are MobyDataInstances below + Map primaryParams = new HashMap(); + Map secondaryParams = new HashMap(); + + // To store the primary input parameter name as given by the user, + // in case we need it later on for parameter renaming... + String primaryParamName = null; + + for(Map.Entry subentry: query.entrySet()){ + String name = subentry.getKey(); + MobyDataInstance param = subentry.getValue(); + if(param == null){ + throw new MobyException("Query " + queryName + + " contained a null input parameter (" + name + ")"); + } + else if(param instanceof MobyPrimaryData){ + primaryParams.put(name, (MobyPrimaryData) param); + primaryParamName = name; + } + else if(param instanceof MobySecondaryData){ + secondaryParams.put(name, (MobySecondaryData) param); + } + else{ + System.err.println("Input parameter " + name + " (query " + queryName + + ") was not a MobyPrimaryData or MobySecondaryData " + + "as expected, but rather was of class " + param.getClass().getName()); + } + } + + if(inputs != null && inputs.length != primaryParams.size()){ + throw new MobyException("Service " + mobyService.getName() + " was provided " + + primaryParams.size() + + " primary input parameter(s), but takes " + inputs.length + + " (query " + queryName + ")"); + } + if(secondaries != null){ + // If no secondaries provided, fill them in by default + if(secondaries.length != 0){ + for(MobySecondaryData secondary: secondaries){ + if(!secondaryParams.containsKey(secondary.getName())){ + if(debug){ + System.err.println("Setting default secondary param value for missing param " + secondary); + } + query.put(secondary.getName(), new MobyDataSecondaryInstance(secondary)); + } + } + } + if(secondaries.length != secondaryParams.size()){ + throw new MobyException("Service " + mobyService.getName() + " was provided " + + secondaryParams.size() + + " secondary input parameter(s), but takes " + secondaries.length + + " (query " + queryName + "). Extra secondary" + + " parameters must have been specified"); + } + } + + // If there was one anonymous input, assign the name automatically in + // the case the service requires it to be named. This is the only + // unambiguous case in which we can do this. + if(inputs.length == 1){ + String serviceParamName = inputs[0].getName(); // name as req'd by the service + + // name isn't the same as required currently + if(serviceParamName != null && serviceParamName.length() > 0 && + !serviceParamName.equals(primaryParamName)){ + // take out the old parameter + MobyPrimaryData theInputToRename = (MobyPrimaryData) query.remove(primaryParamName); + + // Add in the same parameter, but with the appropriate name + query.put(serviceParamName, (MobyDataInstance) theInputToRename); + } + } + } + + ByteArrayOutputStream mobyRequest = new ByteArrayOutputStream(); + try{ + MobyDataUtils.toXMLDocument(mobyRequest, data); + } + catch(MobyException me){ + throw me; + } + catch(Exception e){ + e.printStackTrace(); + throw new MobyException("Could not create MOBY payload XML from input data: " +e); + } + + if(debug){ + debugPS.println("Input to MOBY Service is:"); + debugPS.print(mobyRequest.toString()); + } + + return mobyRequest.toString(); + } + + /** + * A method that sets up the execution environment for and runs a compiled XPath statement against a DOM node + * You should call releaseXPath when you're done with the results + * @return the list of Nodes that satisfy the XPath in this Node's context + */ + protected NodeList runXPath(XPath xpath, Node n) throws TransformerException{ + NodeList result = null; + int dtm_node_handle = xpath_context.getDTMHandleFromNode(n); + PrefixResolver node_prefix_resolver = new PrefixResolverDefault(n); + XObject xobject = xpath.execute(xpath_context, n, node_prefix_resolver); + if(xobject instanceof XNodeSet){ + result = ((XNodeSet) xobject).nodelist(); + } + else if(debug && xobject != null){ + debugPS.println("Output of XPath was not a XNodeSet as expected, found " + xobject.getClass().getName()); + debugPS.flush(); + } + return result; + } + + protected void releaseXPath(Node n){ + xpath_context.release(xpath_context.getDTM(xpath_context.getDTMHandleFromNode(n)), false); + } +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java 2008/11/26 08:53:43 1.13 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java 2008/12/03 15:21:13 1.14 @@ -1,429 +1,487 @@ -// BaseClient.java -// -// Created: August 2005 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.client; - -import java.io.StringReader; -import java.net.MalformedURLException; -import java.net.URL; - -import org.apache.axis.client.Call; -import org.apache.commons.lang.StringUtils; -import org.biomoby.shared.Central; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.parser.JDOMUtils; -import org.biomoby.shared.parser.MobyJob; -import org.biomoby.shared.parser.MobyPackage; -import org.biomoby.shared.parser.MobyTags; -import org.biomoby.shared.parser.ServiceException; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.input.SAXBuilder; -import org.tulsoft.shared.GException; -import org.tulsoft.tools.soap.axis.AxisCall; - -/** - * This is a base class for Biomoby clients. It takes care about converting user input into Biomoby XML, sending it in a - * SOAP message to a Biomoby service, waiting for the response and parsing it from Biomoby XML. It also divides requests - * and responses into so-called jobs - each of them corresponds to a Biomoby query (a Biomoby single network - * request may contain more queries/jobs). - *

- * - * Any client can override various methods - but the ones she/he must override in a subclass are those - * telling what service to call ({@link #getServiceLocator}), what data to put in a request ({@link #fillRequest(MobyJob,MobyPackage) fillRequest}), - * and what to do with a response ({@link #useResponse(MobyJob,MobyPackage) useResponse}. - *

- * - * @author Martin Senger - * @version $Id$ - */ - -abstract public class BaseClient { - private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( BaseClient.class ); - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - static protected boolean notEmpty(String value) { - return StringUtils.isNotBlank( value ); - } - static protected boolean isEmpty(String value) { - return StringUtils.isBlank( value ); - } - - /******************************************************************************************************************* - * The main method that packs input data, invokes a BioMoby service and uses its response. Use this method if the - * input data should have just one job (which is a usual case) - otherwise use method {@link #process(int)}. - *

- * - * @throws MobyException if (a) a sub-class throws it during the filling data or using response, or (b) a Biomoby - * service invocation fails - ******************************************************************************************************************/ - public void process() throws MobyException { - process( 1 ); - } - - /******************************************************************************************************************* - * The main method that packs input data, invokes a BioMoby service and uses its response. The input data may - * consist from more than one job (query) - the 'jobCount' is a suggestion how many jobs will be included, but this - * can be changed by the implementing sub-class. - *

- * - * Usually a client developer does not need to overwrite this method. She or he makes the real input data filling in - * the {@link #fillRequest} method, and uses the response in the {@link #useResponse} method. - *

- * - * @throws MobyException if (a) a sub-class throws it during the filling data or using response, or (b) a Biomoby - * service invocation fails - ******************************************************************************************************************/ - public void process(int jobCount) throws MobyException { - - String xmlResponse = null; - - // input: raw-level processing - String xmlInput = fillRequest(); - if ( xmlInput != null ) { - if ( ( xmlInput = interceptRequest( xmlInput ) ) == null ) - return; - } - - // input: usual processing (i.e. collect XML in iterations) - else { - MobyPackage mobyInput = new MobyPackage(); - if ( !fillRequest( mobyInput, jobCount ) ) - return; - xmlInput = mobyInput.toXML(); - if ( ( xmlInput = interceptRequest( xmlInput ) ) == null ) - return; - } - - // calling service - xmlResponse = callRemoteService( xmlInput ); - - // output: raw-level processing - if ( !useResponse( xmlResponse ) ) - return; - - // output: usual processing (again by iterations) - MobyPackage mobyResponse = MobyPackage.createFromXML( xmlResponse ); - useResponse( mobyResponse ); - } - - public String interceptRequest(String xmlInput) throws MobyException { - return xmlInput; - } - - /******************************************************************************************************************* - * Create raw XML input. Override this method if you have already an input XML, or you want to create it yourself. - *

- * - * @return a full XML input for a Biomoby service (in this case no other fillRequest methods will - * called); return null if no XML was created and a usual process to gather it will be used - * - * @throws MobyException if an XML cannot be created - ******************************************************************************************************************/ - public String fillRequest() throws MobyException { - return null; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected String filterMobyResponseType(Object result) throws MobyException { - if ( result instanceof String ) - return ( String ) result; - else if ( result instanceof byte[] ) - return new String( ( byte[] ) result ); - else - throw new MobyException( - "The Biomoby data should be sent/received either as type String or base64/byte[]. " - + "But they are of type '" + result.getClass().getName() + "'." ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected String callBiomobyService(MobyServiceLocator locator, String xmlInput) throws MobyException { - - MobyService service = locator.getService(); - String serviceName = service.getName(); - boolean asBytes = locator.isAsBytes(); - String serviceEndpoint = service.getURL(); - int timeout = locator.getSuggestedTimeout(); - - try { - URL target = new URL( serviceEndpoint ); - AxisCall call = new AxisCall( target, timeout ); - // to allow service calls which need authentication - setAuthentication( call.getCall() ); - call.getCall().setSOAPActionURI( MobyService.BIOMOBY_SERVICE_URI + "#" + serviceName ); - - return filterMobyResponseType( call.doCall( MobyService.BIOMOBY_SERVICE_URI, serviceName, - new Object[]{sendingFilter( xmlInput, asBytes )} ) ); - } - catch ( MalformedURLException e ) { - throw new MobyException( "Service endpoint '" + serviceEndpoint + "' is not a valid URL." ); - } - catch ( GException e ) { - throw new MobyException( e.getMessage(), e ); - } - } - - /** - * Sets the authentication for the call. The default implementation does not do anything ! - * - * @param call - */ - protected void setAuthentication(Call call) { - return; - } - - // - protected Object sendingFilter(String input, boolean asBytes) { - if ( asBytes ) { - log.debug( "Data sent as a byte array" ); - return input.getBytes(); - } - else { - return input; - } - } - - /******************************************************************************************************************* - * Call a SOAP-based BioMoby service. In order to find what service to call and what are its characteristics (such - * as its endpoint) it will call method {@link #getServiceLocator} that should be implemented by a sub-class. - *

- * - * Once it has the service locator, this class does one of the following, in this order: - *

    - * - *
  • The locator must contain at least a service name. If it does not, an exception is raised. - * - *
  • If the locator contains a service endpoint, a call is made to this endpoint, using also the service name as - * a method name. - * - *
  • If the locator has a registry endpoint, an enquiry to the registry is made to find an endpoint of a service - * corresponding with the given service name. Once found, the service is called. - * - *
  • The same as the previous one but using a default registry. - * - * @param xmlInput data will be sent to the called Biomoby service - * - * @return service response (still in XML) - * - * @throws MobyException (a) if service call (or a call to registry; for example because the registry does not know - * given service) fails, or (b) if the used {@link MobyServiceLocator} does not contain a service name. - * - ******************************************************************************************************************/ - public String callRemoteService(String xmlInput) throws MobyException { - - // 1) service name is a must - MobyServiceLocator locator = getServiceLocator(); - MobyService service = locator.getService(); - if ( service == null ) - throw new MobyException( "MobyService locator returned an empty service object.\n" - + "I do not know what service to call..." ); - String serviceName = service.getName(); - if ( isEmpty( serviceName ) || MobyService.DUMMY_NAME.equals( serviceName ) ) - throw new MobyException( "MobyService locator returned an empty service name.\n" - + "I do not know what service to call..." ); - - // 2) try service endpoint - String serviceEndpoint = service.getURL(); - if ( notEmpty( serviceEndpoint ) ) - return callBiomobyService( locator, xmlInput ); - - // 3) find service endpoint in a Biomoby registry - Central worker = new CentralImpl( locator.getRegistryEndpoint(), locator.getRegistryNamespace() ); - MobyService[] services = worker.findService( service ); - if ( services == null || services.length == 0 ) - throw new MobyException( "Service " + service.toShortString() + " is not known in Biomoby registry: \n" - + "\t" + worker.getRegistryEndpoint() + "\n" + "\t" + worker.getRegistryNamespace() ); - // ...and call the service - serviceEndpoint = services[ 0 ].getURL(); - if ( notEmpty( serviceEndpoint ) ) { - service.setURL( serviceEndpoint ); - return callBiomobyService( locator, xmlInput ); - } - - // what else can I do? - throw new MobyException( "Registry has not returned any URL for service " + service.toShortString() ); - } - - /******************************************************************************************************************* - * Fill the whole 'mobyInput' - put there any number of jobs (queries) as you wish (you do not need to follow the - * 'jobCount' hint suggesting how many jobs should be put there). - *

    - * - * Usually there is not need to overwrite this method. It serves as an inter-mediator between the main - * {@link #process} method and the individual request fillings (done by a sub-class in method - * {@link #fillRequest(MobyJob,MobyPackage)}). - *

    - * - * @return false if you wish to cancel whole request (nothing will be sent to a Biomoby service); otherwise return - * true. - * - * @param mobyInput is an empty shell that you are supposed to fill with the input data for a Biomoby service - * execution - * - * @param jobCount is only a suggestion how many requests/job should be created (it comes from the {@link #process} - * method) - but it does not need to be obeyed - * - ******************************************************************************************************************/ - public boolean fillRequest(MobyPackage mobyInput, int jobCount) throws MobyException { - - if ( jobCount < 0 ) - jobCount = 0; - for ( int i = 0; i < jobCount; i++ ) { - MobyJob request = new MobyJob( "job_" + i ); - if ( !fillRequest( request, mobyInput ) ) - break; - mobyInput.addJob( request ); - } - return ( mobyInput.size() > 0 ); - } - - /******************************************************************************************************************* - * A raw-level processing. Use it if you need access to raw XML coming from a service. - *

    - * - * @param xmlResponse is a raw XML response returned from a BioMoby service - * - * @return false if the response should be considered fully processed (in this case no other 'useResponse' will be - * called); true indicates that normal processing of the response will follow; by default, this class (BaseClient) - * returns true - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'mobyResponse' is broken - ******************************************************************************************************************/ - public boolean useResponse(String xmlResponse) throws MobyException { - return true; - } - - /******************************************************************************************************************* - * A high-level processing. Use it if you need access to all jobs (queries) - that returned from a service - in the - * same time. Otherwise use the processing on the job level (method {@link #useResponse(MobyJob,MobyPackage)}. - *

    - * - * @param mobyResponse is a full response returned from a BioMoby service - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'mobyResponse' is broken - ******************************************************************************************************************/ - public void useResponse(MobyPackage mobyResponse) throws MobyException { - - // iterate over all input jobs - for ( int i = 0; i < mobyResponse.size(); i++ ) { - if ( !useResponse( mobyResponse.getJob( i ), mobyResponse ) ) - return; - } - } - - /******************************************************************************************************************* - * Extracts errors from a raw service response. It is iseful when one does not want to create a whole - * MobyPackage from a response, but just find whether a response is good or bad. - *

    - * - * @param xmlResponse is a full response returned from a BioMoby service - * - * @return a slightly formatted list of exceptions (of severity error) extracted from the response; or - * null if there are no errors there - ******************************************************************************************************************/ - public String errorsInResponse(String xmlResponse) { - try { - StringBuffer buf = new StringBuffer(); - SAXBuilder builder = new SAXBuilder(); - Document doc = builder.build( new StringReader( xmlResponse ) ); - Element root = doc.getRootElement(); - Element mobyContent = JDOMUtils.getChild( root, MobyTags.MOBYCONTENT ); - Element serviceNotes = JDOMUtils.getChild( mobyContent, MobyTags.SERVICENOTES ); - ServiceException[] exceptions = ServiceException.extractExceptions( serviceNotes ); - for ( int i = 0; i < exceptions.length; i++ ) { - if ( exceptions[ i ].getSeverity() != ServiceException.ERROR ) - continue; - if ( buf.length() > 0 ) - buf.append( "\n" ); - buf.append( exceptions[ i ].getErrorCodeAsString() ); - buf.append( ": " ); - buf.append( exceptions[ i ].getMessage() ); - } - return ( buf.length() == 0 ? null : new String( buf ) ); - - } - catch ( Exception e ) { - return e.toString(); - } - } - - // - // Abstract methods - // - - /******************************************************************************************************************* - * Return characteristics of a BioMoby service that will be called, and that reveal where to find such service. - *

    - * - * @see #callRemoteService - * - * @return an object defining a location of a BioMoby service - * @throws MobyException if service locator cannot be returned/created (e.g. because there is not enough information - * about what service to call) - ******************************************************************************************************************/ - abstract public MobyServiceLocator getServiceLocator() throws MobyException; - - /******************************************************************************************************************* - * Crate data (fill them into 'request') for one Moby job (query). The request will be sent within given - * 'inputContext' - but it is not yet there (because you may wish not to put it there - see the return value), and - * it is not the task of this method to put it there (just fill the 'request'). - *

    - * - * This is a method that should be implemented by a client developer, and it is the place where the client's - * business logic sits. - *

    - * - * @return true if this request should be included into the input data (package) that will be sent to a biomoby - * service; or return false if you do not wish to create any more requests for this particular package (also - * this 'request' will not be used) - * - * @param request is an object that you are supposed to fill with input data for one service invocation; it already - * has a name (so called 'query id' in the BioMoby speak) but you are free to change it - * - * @param inputContext is an envelope where all requests will be stored and sent to a Biomoby service; you do not - * need to do anything with it here unless you wish; note that all already created requests are there, - * but not the one you are just creating in this method - * - * @throws MobyException if you need so (from whatever reason in your business logic); if thrown then nothing will - * be sent to a Biomoby service - * - ******************************************************************************************************************/ - abstract public boolean fillRequest(MobyJob request, MobyPackage inputContext) throws MobyException; - - /******************************************************************************************************************* - * Process a single job returned from a BioMoby service. - *

    - * - * This is a method that should be implemented by a client developer, and it is the place where the client's - * business logic using the response sits. - *

    - * - * @param response is an object that you are supposed to use - * - * @param responseContext is an envelope where the full response (all its jobs) is located; you do not need to do - * anything with it here unless you wish (e.g. it gives you knowledge about how many jobs are in the full - * response, or it gives you access to the so-called 'service notes') - * - * @return false if you do not wish to get any more responses/jobs; otherwise return true - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'response' is broken - * - ******************************************************************************************************************/ - abstract public boolean useResponse(MobyJob response, MobyPackage responseContext) throws MobyException; - -} +// BaseClient.java +// +// Created: August 2005 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.client; + +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.parser.JDOMUtils; +import org.biomoby.shared.Central; +import org.biomoby.client.CentralImpl; +import org.biomoby.shared.parser.MobyPackage; +import org.biomoby.shared.parser.MobyJob; +import org.biomoby.shared.parser.ServiceException; +import org.biomoby.shared.parser.MobyTags; + +import org.tulsoft.tools.soap.axis.AxisCall; +import org.tulsoft.shared.GException; + +import org.apache.axis.client.Call; +import org.apache.commons.lang.StringUtils; + +import org.jdom.input.SAXBuilder; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.Namespace; + +import java.net.URL; +import java.net.MalformedURLException; +import java.io.StringReader; + +/** + * This is a base class for Biomoby clients. It takes care about + * converting user input into Biomoby XML, sending it in a SOAP + * message to a Biomoby service, waiting for the response and parsing + * it from Biomoby XML. It also divides requests and responses into + * so-called jobs - each of them corresponds to a Biomoby + * query (a Biomoby single network request may contain more + * queries/jobs).

    + * + * Any client can override various methods - but the ones she/he + * must override in a subclass are those telling what service + * to call ({@link #getServiceLocator}), what data to put in a request + * ({@link #fillRequest(MobyJob,MobyPackage) fillRequest}), and what + * to do with a response ({@link #useResponse(MobyJob,MobyPackage) + * useResponse}.

    + * + * @author Martin Senger + * @version $Id$ + */ + +abstract public class BaseClient { + + private static org.apache.commons.logging.Log log = + org.apache.commons.logging.LogFactory.getLog (BaseClient.class); + + /************************************************************************** + * + *************************************************************************/ + static protected boolean notEmpty (String value) { + return StringUtils.isNotBlank (value); + } + static protected boolean isEmpty (String value) { + return StringUtils.isBlank (value); + } + + /************************************************************************** + * The main method that packs input data, invokes a BioMoby + * service and uses its response. Use this method if the input + * data should have just one job (which is a usual case) - + * otherwise use method {@link #process(int)}.

    + * + * @throws MobyException if (a) a sub-class throws it during the + * filling data or using response, or (b) a Biomoby service + * invocation fails + *************************************************************************/ + public void process() + throws MobyException { + process (1); + } + + /************************************************************************** + * The main method that packs input data, invokes a BioMoby + * service and uses its response. The input data may consist from + * more than one job (query) - the 'jobCount' is a suggestion how + * many jobs will be included, but this can be changed by the + * implementing sub-class.

    + * + * Usually a client developer does not need to overwrite this + * method. She or he makes the real input data filling in the + * {@link #fillRequest} method, and uses the response in the + * {@link #useResponse} method.

    + * + * @throws MobyException if (a) a sub-class throws it during the + * filling data or using response, or (b) a Biomoby service + * invocation fails + *************************************************************************/ + public void process (int jobCount) + throws MobyException { + + String xmlResponse = null; + + // input: raw-level processing + String xmlInput = fillRequest(); + if (xmlInput != null) { + if ( (xmlInput = interceptRequest (xmlInput)) == null ) + return; + } + + // input: usual processing (i.e. collect XML in iterations) + else { + MobyPackage mobyInput = new MobyPackage(); + if (! fillRequest (mobyInput, jobCount)) return; + xmlInput = mobyInput.toXML(); + if ( (xmlInput = interceptRequest (xmlInput)) == null ) + return; + } + + // calling service + xmlResponse = callRemoteService (xmlInput); + + // output: raw-level processing + if (! useResponse (xmlResponse)) return; + + // output: usual processing (again by iterations) + MobyPackage mobyResponse = MobyPackage.createFromXML (xmlResponse); + useResponse (mobyResponse); + } + + public String interceptRequest (String xmlInput) + throws MobyException { + return xmlInput; + } + + /************************************************************************** + * Create raw XML input. Override this method if you have already + * an input XML, or you want to create it yourself.

    + * + * @return a full XML input for a Biomoby service (in this case no + * other fillRequest methods will called); return null if + * no XML was created and a usual process to gather it will be used + * + * @throws MobyException if an XML cannot be created + *************************************************************************/ + public String fillRequest() + throws MobyException { + return null; + } + + /************************************************************************** + * + *************************************************************************/ + protected String filterMobyResponseType (Object result) + throws MobyException { + if (result instanceof String) + return (String)result; + else if (result instanceof byte[]) + return new String ((byte[])result); + else + throw new MobyException + ("The Biomoby data should be sent/received either as type String or base64/byte[]. " + + "But they are of type '" + result.getClass().getName() + "'."); + } + + /************************************************************************** + * + *************************************************************************/ + protected String callBiomobyService (MobyServiceLocator locator, + String xmlInput) + throws MobyException { + + + MobyService service = locator.getService(); + String serviceName = service.getName(); + boolean asBytes = locator.isAsBytes(); + String serviceEndpoint = service.getURL(); + int timeout = locator.getSuggestedTimeout(); + + try { + URL target = new URL (serviceEndpoint); + AxisCall call = new AxisCall (target, timeout); + // if the locator has authentication information. + if(locator.hasAuthentication()) { + call.getCall().setProperty( Call.USERNAME_PROPERTY, locator.getUser() ); + call.getCall().setProperty( Call.PASSWORD_PROPERTY, locator.getPassword() ); + } + call.getCall().setSOAPActionURI (MobyService.BIOMOBY_SERVICE_URI + "#" + serviceName); + return filterMobyResponseType + (call.doCall (MobyService.BIOMOBY_SERVICE_URI, + serviceName, + new Object[] { sendingFilter (xmlInput, asBytes) })); + } catch (MalformedURLException e) { + throw new MobyException ("Service endpoint '" + serviceEndpoint + + "' is not a valid URL."); + } catch (GException e) { + throw new MobyException (e.getMessage(), e); + } + } + + // + protected Object sendingFilter (String input, boolean asBytes) { + if (asBytes) { + log.debug ("Data sent as a byte array"); + return input.getBytes(); + } else { + return input; + } + } + + /************************************************************************** + * Call a SOAP-based BioMoby service. In order to find what + * service to call and what are its characteristics (such as its + * endpoint) it will call method {@link #getServiceLocator} that + * should be implemented by a sub-class.

    + * + * Once it has the service locator, this class does one of the + * following, in this order:

      + * + *
    • The locator must contain at least a service name. If it + * does not, an exception is raised. + * + *
    • If the locator contains a service endpoint, a call is + * made to this endpoint, using also the service name as a + * method name. + * + *
    • If the locator has a registry endpoint, an enquiry to + * the registry is made to find an endpoint of a service + * corresponding with the given service name. Once found, the + * service is called. + * + *
    • The same as the previous one but using a default + * registry. + * + * @param xmlInput data will be sent to the called Biomoby service + * + * @return service response (still in XML) + * + * @throws MobyException (a) if service call (or a call to + * registry; for example because the registry does not know given + * service) fails, or (b) if the used {@link MobyServiceLocator} + * does not contain a service name. + * + *************************************************************************/ + public String callRemoteService (String xmlInput) + throws MobyException { + + // 1) service name is a must + MobyServiceLocator locator = getServiceLocator(); + MobyService service = locator.getService(); + if (service == null) + throw new MobyException ("MobyService locator returned an empty service object.\n" + + "I do not know what service to call..."); + String serviceName = service.getName(); + if (isEmpty (serviceName) || + MobyService.DUMMY_NAME.equals (serviceName)) + throw new MobyException ("MobyService locator returned an empty service name.\n" + + "I do not know what service to call..."); + + // 2) try service endpoint + String serviceEndpoint = service.getURL(); + if (notEmpty (serviceEndpoint)) + return callBiomobyService (locator, xmlInput); + + // 3) find service endpoint in a Biomoby registry + Central worker = new CentralImpl (locator.getRegistryEndpoint(), + locator.getRegistryNamespace()); + MobyService[] services = worker.findService (service); + if (services == null || services.length == 0) + throw new MobyException ("Service " + service.toShortString() + + " is not known in Biomoby registry: \n" + + "\t" + worker.getRegistryEndpoint() + "\n" + + "\t" + worker.getRegistryNamespace()); + // ...and call the service + serviceEndpoint = services[0].getURL(); + if (notEmpty (serviceEndpoint)) { + service.setURL (serviceEndpoint); + return callBiomobyService (locator, xmlInput); + } + + // what else can I do? + throw new MobyException ("Registry has not returned any URL for service " + + service.toShortString()); + } + + /************************************************************************** + * Fill the whole 'mobyInput' - put there any number of jobs + * (queries) as you wish (you do not need to follow the 'jobCount' + * hint suggesting how many jobs should be put there).

      + * + * Usually there is not need to overwrite this method. It serves + * as an inter-mediator between the main {@link #process} method + * and the individual request fillings (done by a sub-class in + * method {@link #fillRequest(MobyJob,MobyPackage)}).

      + * + * @return false if you wish to cancel whole request (nothing will + * be sent to a Biomoby service); otherwise return true. + * + * @param mobyInput is an empty shell that you are supposed to + * fill with the input data for a Biomoby service execution + * + * @param jobCount is only a suggestion how many requests/job + * should be created (it comes from the {@link #process} method) - + * but it does not need to be obeyed + * + *************************************************************************/ + public boolean fillRequest (MobyPackage mobyInput, int jobCount) + throws MobyException { + + if (jobCount < 0) jobCount = 0; + for (int i = 0; i < jobCount; i++) { + MobyJob request = new MobyJob ("job_" + i); + if (! fillRequest (request, mobyInput)) + break; + mobyInput.addJob (request); + } + return (mobyInput.size() > 0); + } + + /************************************************************************** + * A raw-level processing. Use it if you need access to raw XML + * coming from a service.

      + * + * @param xmlResponse is a raw XML response returned from a + * BioMoby service + * + * @return false if the response should be considered fully + * processed (in this case no other 'useResponse' will be called); + * true indicates that normal processing of the response will + * follow; by default, this class (BaseClient) returns true + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'mobyResponse' is broken + *************************************************************************/ + public boolean useResponse (String xmlResponse) + throws MobyException { + return true; + } + + /************************************************************************** + * A high-level processing. Use it if you need access to all jobs + * (queries) - that returned from a service - in the same time. + * Otherwise use the processing on the job level (method {@link + * #useResponse(MobyJob,MobyPackage)}.

      + * + * @param mobyResponse is a full response returned from a BioMoby + * service + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'mobyResponse' is broken + *************************************************************************/ + public void useResponse (MobyPackage mobyResponse) + throws MobyException { + + // iterate over all input jobs + for (int i = 0; i < mobyResponse.size(); i++) { + if (! useResponse (mobyResponse.getJob (i), + mobyResponse)) + return; + } + } + + /************************************************************************** + * Extracts errors from a raw service response. It is iseful when + * one does not want to create a whole MobyPackage from a + * response, but just find whether a response is good or bad.

      + * + * @param xmlResponse is a full response returned from a BioMoby + * service + * + * @return a slightly formatted list of exceptions (of severity + * error) extracted from the response; or null if there + * are no errors there + *************************************************************************/ + public String errorsInResponse (String xmlResponse) { + try { + StringBuffer buf = new StringBuffer(); + SAXBuilder builder = new SAXBuilder(); + Document doc = + builder.build (new StringReader (xmlResponse)); + Element root = doc.getRootElement(); + Element mobyContent = JDOMUtils.getChild (root, MobyTags.MOBYCONTENT); + Element serviceNotes = JDOMUtils.getChild (mobyContent, MobyTags.SERVICENOTES); + ServiceException[] exceptions = + ServiceException.extractExceptions (serviceNotes); + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i].getSeverity() != ServiceException.ERROR) + continue; + if (buf.length() > 0) + buf.append ("\n"); + buf.append (exceptions[i].getErrorCodeAsString()); + buf.append (": "); + buf.append (exceptions[i].getMessage()); + } + return (buf.length() == 0 ? null : new String (buf)); + + } catch (Exception e) { + return e.toString(); + } + } + + + // + // Abstract methods + // + + /************************************************************************** + * Return characteristics of a BioMoby service that will be + * called, and that reveal where to find such service.

      + * + * @see #callRemoteService + * + * @return an object defining a location of a BioMoby service + * @throws MobyException if service locator cannot be + * returned/created (e.g. because there is not enough information + * about what service to call) + *************************************************************************/ + abstract public MobyServiceLocator getServiceLocator() + throws MobyException; + + /************************************************************************** + * Crate data (fill them into 'request') for one Moby job + * (query). The request will be sent within given 'inputContext' - + * but it is not yet there (because you may wish not to put it + * there - see the return value), and it is not the task of this + * method to put it there (just fill the 'request').

      + * + * This is a method that should be implemented by a client + * developer, and it is the place where the client's business + * logic sits.

      + * + * @return true if this request should be included into the input + * data (package) that will be sent to a biomoby service; or + * return false if you do not wish to create any more requests for + * this particular package (also this 'request' will not be used) + * + * @param request is an object that you are supposed to fill with + * input data for one service invocation; it already has a name + * (so called 'query id' in the BioMoby speak) but you are free to change it + * + * @param inputContext is an envelope where all requests will be + * stored and sent to a Biomoby service; you do not need to do + * anything with it here unless you wish; note that all already + * created requests are there, but not the one you are just + * creating in this method + * + * @throws MobyException if you need so (from whatever reason in + * your business logic); if thrown then nothing will be sent to a + * Biomoby service + * + *************************************************************************/ + abstract public boolean fillRequest (MobyJob request, MobyPackage inputContext) + throws MobyException; + + /************************************************************************** + * Process a single job returned from a BioMoby service.

      + * + * This is a method that should be implemented by a client + * developer, and it is the place where the client's business + * logic using the response sits.

      + * + * @param response is an object that you are supposed to use + * + * @param responseContext is an envelope where the full response + * (all its jobs) is located; you do not need to do anything with + * it here unless you wish (e.g. it gives you knowledge about how + * many jobs are in the full response, or it gives you access to + * the so-called 'service notes') + * + * @return false if you do not wish to get any more + * responses/jobs; otherwise return true + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'response' is broken + * + *************************************************************************/ + abstract public boolean useResponse (MobyJob response, + MobyPackage responseContext) + throws MobyException; + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2006/02/19 18:42:55 1.4 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/03 15:21:13 1.5 @@ -33,6 +33,8 @@ protected String registryNamespace; protected boolean asBytes = false; protected int timeout = 0; + protected String user; + protected String password; /************************************************************************** * Default constructor. @@ -131,6 +133,44 @@ public void setAsBytes (boolean enabled) { asBytes = enabled; } - - + + /***************************************** + * Sets the user for authentication + * @param user + ***************************************/ + public void setUser(String user) { + this.user = user; + } + + /*************************************** + * Sets the password for authentication + * @param password + ***************************************/ + public void setPassword(String password) { + this.password = password; + } + + /****************************************** + * Returns the user for the authentication + * @return user + ******************************************/ + public String getUser() { + return user; + } + + /********************************************** + * Returns the password for the authentication + * @return password + **********************************************/ + public String getPassword() { + return password; + } + + /*************************************************** + * Returns true if the user AND the password is set + * @return + ***************************************************/ + public boolean hasAuthentication() { + return user != null && password != null; + } } From groscurt at dev.open-bio.org Wed Dec 3 07:09:41 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 07:09:41 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031209.mB3C9f1X011972@dev.open-bio.org> groscurt Wed Dec 3 07:09:40 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv11937/src/main/org/biomoby/client Modified Files: CentralImpl.java Log Message: reformatted it to the original version and removed the System.properties for the service authentication moby-live/Java/src/main/org/biomoby/client CentralImpl.java,1.58,1.59 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java,v retrieving revision 1.58 retrieving revision 1.59 diff -u -r1.58 -r1.59 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/11/26 08:53:43 1.58 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:09:40 1.59 @@ -69,50 +69,53 @@ import java.util.logging.*; /** - * A default implementation of the interface {@link org.biomoby.shared.Central Central} allowing access to a Moby - * registry. - *

      - * This class is supposed to be used by all other clients that wish to communicate with the Moby Registry, but do not - * want to know about all XML details that are necessary for talking with the Moby Central directly. This is an example - * of a client program: - * - *

      + * A default implementation of the
      + * interface {@link org.biomoby.shared.Central Central}
      + * allowing access to a Moby registry.
      + *

      + * This class is supposed to be used by all other clients that wish + * to communicate with the Moby Registry, but do not want to know + * about all XML details that are necessary for talking with the Moby Central + * directly. This is an example of a client program: + *

        * import org.biomoby.shared.Central;
        * import org.biomoby.shared.MobyException;
        * import org.biomoby.client.CentralImpl;
        * import java.util.Map;
        * import java.util.Iterator;
      - * 
      + *
        * public class Test {
      - * 
      - *     public static void main( String[] args ) throws MobyException {
      - * 
      - *         Central worker = new CentralImpl();
      - *         Map authorities = worker.getServiceNamesByAuthority();
      - * 
      - *         for ( Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
      - *             Map.Entry entry = ( Map.Entry ) it.next();
      - *             System.out.println( entry.getKey() );
      - *             String[] names = ( String[] ) entry.getValue();
      - *             for ( int i = 0; i < names.length; i++ )
      - *                 System.out.println( "\t" + names[ i ] );
      - *         }
      - *     }
      + *
      + *    public static void main (String[] args)
      + *       throws MobyException {
      + *
      + *       Central worker = new CentralImpl();
      + *       Map authorities = worker.getServiceNamesByAuthority();
      + *
      + *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
      + *          Map.Entry entry = (Map.Entry)it.next();
      + *          System.out.println (entry.getKey());
      + *          String[] names = (String[])entry.getValue();
      + *          for (int i = 0; i < names.length; i++)
      + *             System.out.println ("\t" + names[i]);
      + *       }
      + *    }
        * }
      - * 
      - * + *
      + * * @author Martin Senger * @version $Id$ */ -public class CentralImpl implements Central, SimpleCache { +public class CentralImpl + implements Central, SimpleCache { private URL endpoint; private String uri; protected boolean debug = false; /** Common central used to if getDefaultCentral() is called */ - protected static Map< String, CentralImpl > defaultCentrals = new HashMap< String, CentralImpl >(); + protected static Map defaultCentrals = new HashMap(); /** Default location (endpoint) of a Moby registry. */ public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; @@ -121,322 +124,368 @@ public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; /** - * The META-INF resource file that will be checked to determine what default class should be instantiated in order - * to create a Central Implementation when getDefaultCentral() is called. + * The META-INF resource file that will be checked to determine what + * default class should be instantiated in order to create a Central Implementation + * when getDefaultCentral() is called. */ public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; /** The class to use for getDefaultCentral if all else fails */ public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; - private static Logger logger = Logger.getLogger( "org.biomoby.client.CentralImpl" ); + private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); - /** - * Thread local that gives each thread its own DocumentBuilderFactory (since it is not thread-safe). Code taken from - * Apache's JaxpUtils. - */ - public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { - protected synchronized Object initialValue() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware( true ); - return dbf; - } - }; - - /******************************************************************************************************************* - * Default constructor. It connects to a default Moby registry (as defined in {@link #DEFAULT_ENDPOINT}) using a - * default namespace (as defined int {@link #DEFAULT_NAMESPACE}). - ******************************************************************************************************************/ - public CentralImpl() throws MobyException { - this( DEFAULT_ENDPOINT, DEFAULT_NAMESPACE ); + /** + * Thread local that gives each thread its own + * DocumentBuilderFactory (since it is not thread-safe). Code taken + * from Apache's JaxpUtils. + */ + public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { + protected synchronized Object initialValue() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware (true); + return dbf; + } + }; + + + /************************************************************************* + * Default constructor. It connects to a default Moby registry + * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace + * (as defined int {@link #DEFAULT_NAMESPACE}). + *************************************************************************/ + public CentralImpl() + throws MobyException { + this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); } - /******************************************************************************************************************* + /************************************************************************* * Constructor allowing to specify which Moby Registry to use. - * - * @throws MobyException - * if 'endpoint' is not a valid URL, or if no DOM parser is available - ******************************************************************************************************************/ - public CentralImpl( String endpoint ) throws MobyException { - this( endpoint, DEFAULT_NAMESPACE ); - } - - /******************************************************************************************************************* - * Constructor allowing to specify which Moby Registry and what namespace to use. If any of the parameters is null, - * its default value is used instead. - *

      - * - * @throws MobyException - * if 'endpoint' is not a valid URL, or if no DOM parser was found - ******************************************************************************************************************/ - public CentralImpl( String endpoint, String namespace ) throws MobyException { - - if ( endpoint == null || "".equals( endpoint.trim() ) ) endpoint = DEFAULT_ENDPOINT; - if ( namespace == null || "".equals( namespace.trim() ) ) namespace = DEFAULT_NAMESPACE; - - try { - this.endpoint = new URL( endpoint ); - } - catch ( MalformedURLException e ) { - throw new MobyException( "Bad URL: " + endpoint ); - } - this.uri = namespace; - - cache = new Hashtable< String, Object >(); - useCache = true; + * + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser is available + *************************************************************************/ + public CentralImpl (String endpoint) + throws MobyException { + this (endpoint, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry and what + * namespace to use. If any of the parameters is null, its default + * value is used instead. + *

      + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser was found + *************************************************************************/ + public CentralImpl (String endpoint, String namespace) + throws MobyException { + + if (endpoint == null || "".equals (endpoint.trim())) + endpoint = DEFAULT_ENDPOINT; + if (namespace == null || "".equals (namespace.trim())) + namespace = DEFAULT_NAMESPACE; + + try { + this.endpoint = new URL (endpoint); + } catch (MalformedURLException e) { + throw new MobyException ("Bad URL: " + endpoint); + } + this.uri = namespace; + + cache = new Hashtable(); + useCache = true; + } + + /************************************************************************* + * Loads a DOM Document from an InputStream. Uses thread-safe + * mechanism. + *************************************************************************/ + public static Document loadDocument (InputStream input) + throws MobyException { + try { + DocumentBuilderFactory dbf + = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); + DocumentBuilder db = dbf.newDocumentBuilder(); + return (db.parse (input)); + } catch (Exception e) { + throw new MobyException ("Problem with reading XML input: " + e.toString(), e); } - - /******************************************************************************************************************* - * Loads a DOM Document from an InputStream. Uses thread-safe mechanism. - ******************************************************************************************************************/ - public static Document loadDocument( InputStream input ) throws MobyException { - try { - DocumentBuilderFactory dbf = ( DocumentBuilderFactory ) DOCUMENT_BUILDER_FACTORIES.get(); - DocumentBuilder db = dbf.newDocumentBuilder(); - return ( db.parse( input ) ); - } - catch ( Exception e ) { - throw new MobyException( "Problem with reading XML input: " + e.toString(), e ); - } } - /******************************************************************************************************************* + /************************************************************************* * Call 'method' with 'parameters' and return its result. - ******************************************************************************************************************/ - protected Object doCall( String method, Object[] parameters ) throws MobyException { - - Call call = null; - try { - Service service = new Service(); - call = ( Call ) service.createCall(); - call.setTargetEndpointAddress( endpoint ); - call.setTimeout( new Integer( 0 ) ); - - String user = System.getProperty( "user" ); - String password = System.getProperty( "password" ); - - if ( user != null && password != null ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, password ); - } - - call.setSOAPActionURI( uri + "#" + method ); - - if ( debug ) { - System.err.println( "METHOD CALL: " + method ); - System.err.println( "------------" ); - if ( parameters.length > 0 ) System.err.println( parameters[ 0 ] + "\n" ); - System.err.println( "------------\n" ); - - Object result = call.invoke( uri, method, parameters ); - - System.err.println( "METHOD RETURN:" ); - System.err.println( "------------" ); - if ( result != null ) System.err.println( result + "\n" ); - System.err.println( "------------\n" ); - - return resultToString( result ); - - } - else { - return resultToString( call.invoke( uri, method, parameters ) ); - } - - } - catch ( AxisFault e ) { - throw new MobyException( formatFault( e, endpoint.toString(), ( call == null ? null : call - .getOperationName() ) ), e ); - // (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); - - } - catch ( Exception e ) { - throw new MobyException( e.toString(), e ); - // e.printStackTrace(); - } - } - - /******************************************************************************************************************* - * Parse the given XML sniplet to find tag 'success'. If it has value '1' look further for tag 'id' and return it - * back (or return an empty string if ID is not there). Otherwise raise an exception with the 'culprit' and with the - * message from the tag 'message'. - *

      - * - * The return value is a two-element long array. The first element is the ID (given by BioMobe registry), and the - * second element is RDF corresponding with the registered object (BioMoby returns this only for service instances, - * so for other objects this will be null). - *

      - * - * This is how the XML is supposed to look: - * - * Success takes the value "1" to indicate success, "0" to indicate failure, and "-1" to indicate "Pending - * Curation". - ******************************************************************************************************************/ - protected String[] checkRegistration( String xml, Object culprit ) throws MobyException, NoSuccessException, - PendingCurationException { - - String id = "", success = "0", message = "", rdf = ""; - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( xml.getBytes() ) ); - Element root = document.getDocumentElement(); - - NodeList children = root.getChildNodes(); - for ( int i = 0; i < children.getLength(); i++ ) { - if ( children.item( i ).getNodeType() != Node.ELEMENT_NODE ) continue; - Element elem = ( Element ) children.item( i ); - if ( elem.getNodeName().equals( "id" ) ) { - if ( elem.getFirstChild() != null ) id = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "success" ) ) { - if ( elem.getFirstChild() != null ) success = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "message" ) ) { - if ( elem.getFirstChild() != null ) message = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "RDF" ) ) { - if ( elem.getFirstChild() != null ) rdf = elem.getFirstChild().getNodeValue(); - } - } - - if ( success.equals( "0" ) ) - throw new NoSuccessException( message, culprit ); - else if ( success.equals( "-1" ) ) throw new PendingCurationException(); - return new String[] { id, rdf }; - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing input data types and their usage in the given - * service. Only data considered primary are included. Note that the main job of converting to XML is done by - * instances of MobyPrimaryData. - * - * The returned XML looks like this: - ******************************************************************************************************************/ - protected String buildPrimaryInputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryInputs = service.getPrimaryInputs(); - buf.append( "\n" ); - for ( int i = 0; i < primaryInputs.length; i++ ) - buf.append( primaryInputs[ i ].toXML() ); - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing input data types and their usage in the given - * service. Only data considered secondary are included. Note that the main job of converting to XML is done by - * instances of MobySecondaryData. - * - * The returned XML looks like this: - * - ******************************************************************************************************************/ - protected String buildSecondaryInputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] secInputs = service.getSecondaryInputs(); - buf.append( "\n" ); - for ( int i = 0; i < secInputs.length; i++ ) { - buf.append( secInputs[ i ].toXML() ); - } - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing output data types and their usage in the given - * service. Only data considered primary are included. Note that the main job of converting to XML is done by - * instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - ******************************************************************************************************************/ - protected String buildOutputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryOutputs = service.getPrimaryOutputs(); - buf.append( "\n" ); - for ( int i = 0; i < primaryOutputs.length; i++ ) - buf.append( primaryOutputs[ i ].toXML() ); - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML represented a query object (an object used to find a service). - * + *************************************************************************/ + protected Object doCall (String method, Object[] parameters) + throws MobyException { + + Call call = null; + try { + Service service = new Service(); + call = (Call) service.createCall(); + call.setTargetEndpointAddress (endpoint); + call.setTimeout (new Integer (0)); + + call.setSOAPActionURI (uri + "#" + method); + + if (debug) { + System.err.println ("METHOD CALL: " + method); + System.err.println ("------------"); + if (parameters.length > 0) + System.err.println (parameters[0] + "\n"); + System.err.println ("------------\n"); + + Object result = call.invoke (uri, method, parameters); + + System.err.println ("METHOD RETURN:"); + System.err.println ("------------"); + if (result != null) + System.err.println (result + "\n"); + System.err.println ("------------\n"); + + return resultToString (result); + + } else { + return resultToString (call.invoke (uri, method, parameters)); + } + + } catch (AxisFault e) { + throw new MobyException + (formatFault (e, + endpoint.toString(), + (call == null ? null : call.getOperationName())), + e); +// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); + + } catch (Exception e) { + throw new MobyException (e.toString(), e); +// e.printStackTrace(); + } + } + + + /************************************************************************** + * Parse the given XML sniplet to find tag 'success'. If it has value '1' + * look further for tag 'id' and return it back (or return an empty string + * if ID is not there). Otherwise raise an exception with the 'culprit' + * and with the message from the tag 'message'.

      + * + * The return value is a two-element long array. The first element + * is the ID (given by BioMobe registry), and the second element + * is RDF corresponding with the registered object (BioMoby + * returns this only for service instances, so for other objects + * this will be null).

      + * + * This is how the XML is supposed to look: + * + * + * + * + * + * + * + * Success takes the value "1" to indicate success, "0" to + * indicate failure, and "-1" to indicate "Pending Curation". + *************************************************************************/ + protected String[] checkRegistration (String xml, Object culprit) + throws MobyException, NoSuccessException, PendingCurationException { + + String id = "", success = "0", message = "", rdf = ""; + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + Element root = document.getDocumentElement(); + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item (i).getNodeType() != Node.ELEMENT_NODE) + continue; + Element elem = (Element)children.item (i); + if (elem.getNodeName().equals ("id")) { + if (elem.getFirstChild() != null) + id = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals("success")) { + if (elem.getFirstChild() != null) + success = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("message")) { + if (elem.getFirstChild() != null) + message = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("RDF")) { + if (elem.getFirstChild() != null) + rdf = elem.getFirstChild().getNodeValue(); + } + } + + if (success.equals ("0")) + throw new NoSuccessException (message, culprit); + else if (success.equals ("-1")) + throw new PendingCurationException(); + return new String[] { id, rdf }; + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * * The returned XML looks like this: - * - * - * - * ServiceTypeTerm ServiceName moby - * http://desired.service.provider; 1|0 1|0 - * 1|0 something .... .... - ******************************************************************************************************************/ - protected String buildQueryObject( MobyService service, String[] keywords, boolean expandObjects, - boolean expandServices, boolean authoritative ) { - if ( service == null ) { - service = new MobyService( "dummy" ); - service.setCategory( "" ); - } - StringBuffer buf = new StringBuffer(); - - buf.append( "\n\n" ); - MobyData[] pi = service.getPrimaryInputs(); - if ( pi.length > 0 ) { - for ( int i = 0; i < pi.length; i++ ) - buf.append( pi[ i ].toXML() ); - } - buf.append( "\n\n" ); - - buf.append( "\n\n" ); - MobyData[] po = service.getPrimaryOutputs(); - if ( po.length > 0 ) { - for ( int i = 0; i < po.length; i++ ) - buf.append( po[ i ].toXML() ); - } - buf.append( "\n\n" ); - - buf.append( "" + service.getType() + "\n" ); - - String name = service.getName(); - if ( !name.equals( "" ) && !name.equals( "dummy" ) && !name.equals( MobyService.DUMMY_NAME ) ) - buf.append( "" + service.getName() + "\n" ); - - String sigURL = service.getSignatureURL(); - if ( !sigURL.equals( "" ) ) buf.append( "" + sigURL + "\n" ); - - buf.append( "" + service.getCategory() + "\n" ); - buf.append( "" + service.getAuthority() + "\n" ); - - buf.append( "" ); - buf.append( expandObjects ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "" ); - buf.append( expandServices ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "" ); - buf.append( authoritative ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "\n" ); - if ( keywords != null && keywords.length > 0 ) { - for ( int i = 0; i < keywords.length; i++ ) { - buf.append( "" ); - buf.append( keywords[ i ] ); - buf.append( "\n" ); - } - } - buf.append( "\n" ); - - return new String( buf ); - } - - /******************************************************************************************************************* - * Extract one or more MobyService objects from the given XML piece. The XML should look like this: - * + * + * + * + *************************************************************************/ + protected String buildPrimaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryInputs = service.getPrimaryInputs(); + buf.append ("\n"); + for (int i = 0; i < primaryInputs.length; i++) + buf.append (primaryInputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * secondary are included. Note that the main job of converting to XML is + * done by instances of MobySecondaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildSecondaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] secInputs = service.getSecondaryInputs(); + buf.append ("\n"); + for (int i = 0; i < secInputs.length; i++) { + buf.append (secInputs[i].toXML()); + } + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing output + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + * + *************************************************************************/ + protected String buildOutputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryOutputs = service.getPrimaryOutputs(); + buf.append ("\n"); + for (int i = 0; i < primaryOutputs.length; i++) + buf.append (primaryOutputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML represented a query object (an object used + * to find a service). + * + * The returned XML looks like this: + * + * + * + * + * + * + * + * + * + * + * + * ServiceTypeTerm + * ServiceName + * moby + * http://desired.service.provider; + * 1|0 + * 1|0 + * 1|0 + * + * something + * .... + * .... + * + *************************************************************************/ + protected String buildQueryObject (MobyService service, + String[] keywords, + boolean expandObjects, + boolean expandServices, + boolean authoritative) { + if (service == null) { + service = new MobyService ("dummy"); + service.setCategory (""); + } + StringBuffer buf = new StringBuffer(); + + buf.append ("\n\n"); + MobyData[] pi = service.getPrimaryInputs(); + if (pi.length > 0) { + for (int i = 0; i < pi.length; i++) + buf.append (pi[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("\n\n"); + MobyData[] po = service.getPrimaryOutputs(); + if (po.length > 0) { + for (int i = 0; i < po.length; i++) + buf.append (po[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("" + service.getType() + "\n"); + + String name = service.getName(); + if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) + buf.append ("" + service.getName() + "\n"); + + String sigURL = service.getSignatureURL(); + if (!sigURL.equals ("")) + buf.append ("" + sigURL + "\n"); + + buf.append ("" + service.getCategory() + "\n"); + buf.append ("" + service.getAuthority() + "\n"); + + buf.append (""); + buf.append (expandObjects ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (expandServices ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (authoritative ? "1" : "0"); + buf.append ("\n"); + + buf.append ("\n"); + if (keywords != null && keywords.length > 0) { + for (int i = 0; i < keywords.length; i++) { + buf.append (""); + buf.append (keywords[i]); + buf.append ("\n"); + } + } + buf.append ("\n"); + + return new String (buf); + } + + /************************************************************************** + * Extract one or more MobyService objects from the given XML piece. + * The XML should look like this: *

            *  <Services>
      -     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
      +     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
            *      <serviceType>Service_Ontology_Term</serviceType>
            *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
            *      <contactEmail>your at email.addy.here</contactEmail>
      @@ -459,359 +508,359 @@
            *    ...
            *  </Services>
            * 
      - * - * @throws MobyException - * if the XML document is invalid - ******************************************************************************************************************/ - public MobyService[] extractServices( String xml ) throws MobyException { - - Document document = loadDocument( new ByteArrayInputStream( xml.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Service" ); - MobyService[] results = new MobyService[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyService service = new MobyService( elem.getAttribute( "serviceName" ) ); - service.setAuthority( elem.getAttribute( "authURI" ) ); - service.setLSID( elem.getAttribute( "lsid" ) ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "Description" ) ) { - service.setDescription( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "Category" ) ) { - service.setCategory( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "URL" ) ) { - service.setURL( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "signatureURL" ) ) { - service.setSignatureURL( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "contactEmail" ) ) { - service.setEmailContact( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "serviceType" ) ) { - service.setType( getFirstValue( children.item( j ) ) ); - MobyServiceType mst = new MobyServiceType( service.getType() ); - NamedNodeMap map = ( children.item( j ).getAttributes() ); - if ( map != null ) { - Node node = map.getNamedItemNS( children.item( j ).getNamespaceURI(), "lsid" ); - if ( node != null ) mst.setLSID( node.getNodeValue() ); - } - service.setServiceType( mst ); - } - else if ( nodeName.equals( "authoritative" ) ) { - String authoritative = getFirstValue( children.item( j ) ); - service.setAuthoritative( authoritative.equals( "1" ) ? true : false ); - } - else if ( nodeName.equals( "Input" ) ) { - // - // - // - // ... - // - // - // ...... - // ...... - // - // - NodeList inputs = children.item( j ).getChildNodes(); - for ( int k = 0; k < inputs.getLength(); k++ ) { - if ( inputs.item( k ).getNodeName().equals( "Simple" ) ) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple( ( Element ) inputs.item( k ) ); - service.addInput( data ); - } - else if ( inputs.item( k ).getNodeName().equals( "Collection" ) ) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet( ( Element ) inputs.item( k ) ); - service.addInput( data ); - } - } - } - else if ( nodeName.equals( "Output" ) ) { - // - // - // - NodeList inputs = children.item( j ).getChildNodes(); - for ( int k = 0; k < inputs.getLength(); k++ ) { - if ( inputs.item( k ).getNodeName().equals( "Simple" ) ) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple( ( Element ) inputs.item( k ) ); - service.addOutput( data ); - } - else if ( inputs.item( k ).getNodeName().equals( "Collection" ) ) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet( ( Element ) inputs.item( k ) ); - service.addOutput( data ); - } - } - - } - else if ( nodeName.equals( "secondaryArticles" ) ) { - // - // ... - // - NodeList parameters = children.item( j ).getChildNodes(); - for ( int k = 0; k < parameters.getLength(); k++ ) { - if ( parameters.item( k ).getNodeName().equals( "Parameter" ) ) { - MobySecondaryData data = new MobySecondaryData( ( Element ) parameters.item( k ) ); - service.addInput( data ); - } - } - } + * @throws MobyException if the XML document is invalid + *************************************************************************/ + public MobyService[] extractServices (String xml) + throws MobyException { + + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + NodeList list = document.getElementsByTagName ("Service"); + MobyService[] results = new MobyService [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyService service = new MobyService (elem.getAttribute ("serviceName")); + service.setAuthority (elem.getAttribute ("authURI")); + service.setLSID (elem.getAttribute ("lsid")); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + service.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Category")) { + service.setCategory (getFirstValue (children.item (j))); + } else if (nodeName.equals ("URL")) { + service.setURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("signatureURL")) { + service.setSignatureURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + service.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("serviceType")) { + service.setType (getFirstValue (children.item (j))); + MobyServiceType mst = new MobyServiceType(service.getType()); + NamedNodeMap map = (children.item (j).getAttributes()); + if (map != null) { + Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); + if (node != null) + mst.setLSID(node.getNodeValue()); + } + service.setServiceType(mst); + } else if (nodeName.equals ("authoritative")) { + String authoritative = getFirstValue (children.item (j)); + service.setAuthoritative (authoritative.equals ("1") ? true : false); + } else if (nodeName.equals ("Input")) { + // + // + // + // ... + // + // + // ...... + // ...... + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addInput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addInput (data); + } + } + } else if (nodeName.equals ("Output")) { + // + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addOutput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addOutput (data); + } + } + + } else if (nodeName.equals ("secondaryArticles")) { + // + // ... + // + NodeList parameters = children.item (j).getChildNodes(); + for (int k = 0; k < parameters.getLength(); k++) { + if (parameters.item (k).getNodeName().equals ("Parameter")) { + MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); + service.addInput (data); + } } - results[ i ] = service; } - return results; + } + results [i] = service; + } + return results; } // protect against null values - protected String getFirstValue( Node child ) { - Node node = child.getFirstChild(); - if ( node == null ) return ""; - String value = node.getNodeValue(); - if ( value == null ) return ""; - return value; + protected String getFirstValue (Node child) { + Node node = child.getFirstChild(); + if (node == null) return ""; + String value = node.getNodeValue(); + if (value == null) return ""; + return value; + } + + protected String getFirstValue (NodeList children) { + if (children.item(0) != null && children.item(0).hasChildNodes()) { + children.item(0).normalize(); + return getFirstValue (children.item(0)); } - - protected String getFirstValue( NodeList children ) { - if ( children.item( 0 ) != null && children.item( 0 ).hasChildNodes() ) { - children.item( 0 ).normalize(); - return getFirstValue( children.item( 0 ) ); - } - return ""; + return ""; } - /******************************************************************************************************************* + /************************************************************************** * * Implementing SimpleCache interface. - * - * Why to have an interface for such trivial thing? Well, because I needed to overwrite the caching mechanism in the - * subclasses so I needed to have all caching functions as separate methods - that's why I have collect them in an - * interface. - * - ******************************************************************************************************************/ - private Hashtable< String, Object > cache; // this is the cache itself - private boolean useCache; // this signal that we are actually caching things + * + * Why to have an interface for such trivial thing? Well, because + * I needed to overwrite the caching mechanism in the subclasses + * so I needed to have all caching functions as separate methods - + * that's why I have collect them in an interface. + * + *************************************************************************/ + private Hashtable cache; // this is the cache itself + private boolean useCache; // this signal that we are actually caching things // not used here - public String createId( String rootName, String semanticType, String syntaxType, long lastModified, Properties props ) { - return ""; // not used here + public String createId (String rootName, + String semanticType, String syntaxType, + long lastModified, + Properties props) { + return ""; // not used here } // check existence of a cached object - public boolean existsInCache( String id ) { - synchronized ( cache ) { - if ( useCache ) - return cache.containsKey( id ); - else - return false; - } + public boolean existsInCache (String id) { + synchronized (cache) { + if (useCache) return cache.containsKey (id); + else return false; + } } // retrieve from cache - public Object getContents( String id ) { - synchronized ( cache ) { - if ( useCache ) - return cache.get( id ); - else - return null; - } + public Object getContents (String id) { + synchronized (cache) { + if (useCache) return cache.get (id); + else return null; + } } // cache an object - public void setContents( String id, java.lang.Object data ) { - synchronized ( cache ) { - if ( useCache ) cache.put( id, data ); - } + public void setContents (String id, java.lang.Object data) { + synchronized (cache) { + if (useCache) cache.put (id, data); + } } // in this implementation, it clears the whole cache, regardless // what 'id' is passed - public void removeFromCache( String id ) { - cache.clear(); + public void removeFromCache (String id) { + cache.clear(); } - /******************************************************************************************************************* - * - * And the other methods related to caching (but not part of the SimpleCache interface). - * - ******************************************************************************************************************/ - - /******************************************************************************************************************* - * By default, caching is enabled to reduce network traffic. Setting this to false will clear the cache, and not - * cache any further calls unless it is set to true again. - *

      - * - * @param shouldCache - * whether retrieveXXX call results should be cached in case they are called again (i.e. don't request - * MobyCentral every time) - ******************************************************************************************************************/ - public void setCacheMode( boolean shouldCache ) { - useCache = shouldCache; - if ( !useCache ) removeFromCache( null ); + /************************************************************************** + * + * And the other methods related to caching (but not part of the + * SimpleCache interface). + * + **************************************************************************/ + + /************************************************************************** + * By default, caching is enabled to reduce network traffic. + * Setting this to false will clear the cache, and not cache any + * further calls unless it is set to true again.

      + * + * @param shouldCache whether retrieveXXX call results should be + * cached in case they are called again (i.e. don't request + * MobyCentral every time) + **************************************************************************/ + public void setCacheMode (boolean shouldCache) { + useCache = shouldCache; + if (! useCache) + removeFromCache (null); } - /******************************************************************************************************************* + /************************************************************************** * Find if caching is currently enabled. - * + * * @return true if caching is enabled - ******************************************************************************************************************/ - public boolean getCacheMode() { - return useCache; + **************************************************************************/ + public boolean getCacheMode(){ + return useCache; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

            * <serviceNames>
      -     *   <serviceName name="serviceName" authURI='authority.info.here'/>
      +     *   <serviceName name="serviceName" authURI='authority.info.here'/>
            *   ...
            *   ...
            * </serviceNames>
            * 
      - * - * @deprecated Replaced by {@link #getServiceNamesByAuthority}. The reason is that this method returns a random - * result if there are more services with the same name but belonging to different authorities. - *

      - * - ******************************************************************************************************************/ - public Map< String, String > getServiceNames() throws MobyException { - - String result = ( String ) doCall( "retrieveServiceNames", new Object[] {} ); - // parse returned XML - Map< String, String > results = new TreeMap< String, String >( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceName" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - results.put( elem.getAttribute( "name" ), elem.getAttribute( "authURI" ) ); - } + * + * @deprecated Replaced by {@link + * #getServiceNamesByAuthority}. The reason is that this method + * returns a random result if there are more services with the + * same name but belonging to different authorities.

      + * + *************************************************************************/ + public Map getServiceNames() + throws MobyException { + + String result = (String)doCall ("retrieveServiceNames", + new Object[] {}); + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + results.put (elem.getAttribute ("name"), + elem.getAttribute ("authURI")); + } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

            * <serviceNames>
      -     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
      +     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
            *   ...
            *   ...
            * </serviceNames>
            * 
      - * - * @return a Map which has authorities as keys, and String arrays with service names as a values. - ******************************************************************************************************************/ - public Map getServiceNamesByAuthority() throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML( result, true ); - } - - /******************************************************************************************************************* - * Similar to {@link #getServiceNamesByAuthority} but the resulting Map contains slightly more. - *

      - * - * @return a Map which has authorities as keys, and arrays of MobyServices as a values. Each MobyService is filled - * with its name, authority and LSID. - ******************************************************************************************************************/ - public Map getServicesByAuthority() throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML( result, false ); + * + * @return a Map which has authorities as keys, and String arrays + * with service names as a values. + *************************************************************************/ + public Map getServiceNamesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, true); + } + + /************************************************************************** + * Similar to {@link #getServiceNamesByAuthority} but the + * resulting Map contains slightly more.

      + * + * @return a Map which has authorities as keys, and arrays of + * MobyServices as a values. Each MobyService is filled with its + * name, authority and LSID. + *************************************************************************/ + public Map getServicesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, false); } // - protected String getServiceNamesByAuthorityAsXML() throws MobyException { - return ( String ) doCall( "retrieveServiceNames", new Object[] {} ); + protected String getServiceNamesByAuthorityAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceNames", + new Object[] {}); } // if onlyNames == true - // Map: authority name -> String[] - // (filled with service namea) + // Map: authority name -> String[] + // (filled with service namea) // else - // Map: authority name -> MobyService[] - // (filled with service name, authority and lsid) - protected Map createServicesByAuthorityFromXML( String result, boolean onlyNames ) throws MobyException { - - // parse returned XML - Map results = new TreeMap( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceName" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String name = elem.getAttribute( "name" ); - String auth = elem.getAttribute( "authURI" ); - Vector< Object > v = ( results.containsKey( auth ) ? ( Vector ) results.get( auth ) - : new Vector< Object >() ); - if ( onlyNames ) { - v.addElement( name ); - } - else { - MobyService ms = new MobyService( name ); - ms.setAuthority( auth ); - ms.setLSID( elem.getAttribute( "lsid" ) ); - v.addElement( ms ); - } - results.put( auth, v ); - } - - // change values of type Vector to MobyService[] or String[] - for ( Iterator it = results.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = ( Map.Entry ) it.next(); - Vector v = ( Vector ) entry.getValue(); - if ( onlyNames ) { - String[] sNames = new String[ v.size() ]; - v.copyInto( sNames ); - entry.setValue( sNames ); - } - else { - MobyService[] mss = new MobyService[ v.size() ]; - v.copyInto( mss ); - entry.setValue( mss ); - } + // Map: authority name -> MobyService[] + // (filled with service name, authority and lsid) + protected Map createServicesByAuthorityFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + String auth = elem.getAttribute ("authURI"); + Vector v = + (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); + if (onlyNames) { + v.addElement (name); + } else { + MobyService ms = new MobyService (name); + ms.setAuthority (auth); + ms.setLSID (elem.getAttribute ("lsid")); + v.addElement (ms); + } + results.put (auth, v); + } + + // change values of type Vector to MobyService[] or String[] + for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + Vector v = (Vector)entry.getValue(); + if (onlyNames) { + String[] sNames = new String [v.size()]; + v.copyInto (sNames); + entry.setValue (sNames); + } else { + MobyService[] mss = new MobyService [v.size()]; + v.copyInto (mss); + entry.setValue (mss); } + } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
            *  <serviceProviders>
      -     *     <serviceProvider name="authority.URI.here"/>
      +     *     <serviceProvider name="authority.URI.here"/>
            *          ...
            *          ...
            *  </serviceProviders>
            * 
      - ******************************************************************************************************************/ - public String[] getProviders() throws MobyException { + *************************************************************************/ + public String[] getProviders() + throws MobyException { - String cacheId = "retrieveServiceProviders"; - String[] cachedResults = ( String[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; + String cacheId = "retrieveServiceProviders"; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; - String result = ( String ) doCall( "retrieveServiceProviders", new Object[] {} ); + String result = (String)doCall ("retrieveServiceProviders", + new Object[] {}); - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceProvider" ); - String[] results = new String[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) - results[ i ] = ( ( Element ) list.item( i ) ).getAttribute( "name" ); + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceProvider"); + String[] results = new String [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) + results[i] = ((Element)list.item (i)).getAttribute ("name"); - // Add this data to the cache in case we get called again - setContents( cacheId, results ); + // Add this data to the cache in case we get called again + setContents (cacheId, results); - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
            *  <serviceTypes>
      -     *     <serviceType name="serviceName" lsid="...">
      +     *     <serviceType name="serviceName" lsid="...">
            *            <Description><![CDATA[free text description here]]></Description>
            *            <contactEmail>...</contactEmail>
            *            <authURI>...</authURI>
      @@ -820,52 +869,57 @@
            *          ...
            *  </serviceTypes>
            * 
      - ******************************************************************************************************************/ - public Map getServiceTypes() throws MobyException { - String result = getServiceTypesAsXML(); - Map results = new TreeMap( getStringComparator() ); - MobyServiceType[] types = createServiceTypesFromXML( result ); - for ( int i = 0; i < types.length; i++ ) { - results.put( types[ i ].getName(), types[ i ].getDescription() ); - } - return results; + *************************************************************************/ + public Map getServiceTypes() + throws MobyException { + String result = getServiceTypesAsXML(); + Map results = new TreeMap (getStringComparator()); + MobyServiceType[] types = createServiceTypesFromXML (result); + for (int i = 0; i < types.length; i++) { + results.put (types[i].getName(), + types[i].getDescription()); + } + return results; } // - protected String getServiceTypesAsXML() throws MobyException { - return ( String ) doCall( "retrieveServiceTypes", new Object[] {} ); + protected String getServiceTypesAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceTypes", + new Object[] {}); } // but be aware that the created MobyServiceTypes are not complete // - they do not have the relationship information; that's why // this method is not public; the full service types are available // from CentralDigest implementations - protected MobyServiceType[] createServiceTypesFromXML( String result ) throws MobyException { + protected MobyServiceType[] createServiceTypesFromXML (String result) + throws MobyException { - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceType" ); - if ( list == null || list.getLength() == 0 ) return new MobyServiceType[] {}; - MobyServiceType[] results = new MobyServiceType[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyServiceType st = new MobyServiceType( elem.getAttribute( "name" ) ); - st.setLSID( elem.getAttribute( "lsid" ) ); - st.setDescription( getFirstValue( elem.getElementsByTagName( "Description" ) ) ); - st.setEmailContact( getFirstValue( elem.getElementsByTagName( "contactEmail" ) ) ); - st.setAuthority( getFirstValue( elem.getElementsByTagName( "authURI" ) ) ); - results[ i ] = st; - } - java.util.Arrays.sort( results ); - return results; + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceType"); + if (list == null || list.getLength() == 0) + return new MobyServiceType[] {}; + MobyServiceType[] results = new MobyServiceType [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); + st.setLSID (elem.getAttribute ("lsid")); + st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = st; + } + java.util.Arrays.sort (results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
            *  <Namespaces>
      -     *     <Namespace name="namespace" lsid="...">
      +     *     <Namespace name="namespace" lsid="...">
            *            <Description><![CDATA[free text description here]]></Description>
            *            <contactEmail>...</contactEmail>
            *            <authURI>...</authURI>
      @@ -874,122 +928,133 @@
            *          ...
            *  </Namespaces>
            * 
      - ******************************************************************************************************************/ - public MobyNamespace[] getFullNamespaces() throws MobyException { + *************************************************************************/ + public MobyNamespace[] getFullNamespaces() + throws MobyException { - String result = getNamespacesAsXML(); - return createNamespacesFromXML( result ); + String result = getNamespacesAsXML(); + return createNamespacesFromXML (result); } // - protected String getNamespacesAsXML() throws MobyException { - return ( String ) doCall( "retrieveNamespaces", new Object[] {} ); + protected String getNamespacesAsXML() + throws MobyException { + return (String)doCall ("retrieveNamespaces", + new Object[] {}); } // - protected MobyNamespace[] createNamespacesFromXML( String result ) throws MobyException { - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getDocumentElement().getElementsByTagName( "Namespace" ); - if ( list == null || list.getLength() == 0 ) { - return new MobyNamespace[] {}; - } - MobyNamespace[] results = new MobyNamespace[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyNamespace nm = new MobyNamespace( elem.getAttribute( "name" ) ); - nm.setLSID( elem.getAttribute( "lsid" ) ); - nm.setDescription( getFirstValue( elem.getElementsByTagName( "Description" ) ) ); - nm.setEmailContact( getFirstValue( elem.getElementsByTagName( "contactEmail" ) ) ); - nm.setAuthority( getFirstValue( elem.getElementsByTagName( "authURI" ) ) ); - results[ i ] = nm; - } + protected MobyNamespace[] createNamespacesFromXML (String result) + throws MobyException { - java.util.Arrays.sort( results ); - return results; + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); + if (list == null || list.getLength() == 0) { + return new MobyNamespace[] {}; + } + MobyNamespace[] results = new MobyNamespace [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); + nm.setLSID (elem.getAttribute ("lsid")); + nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = nm; + } + + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * + * @deprecated Replaced by {@link #getFullNamespaces} that gives + * more information for the same price.

      + *************************************************************************/ + public Map getNamespaces() + throws MobyException { + + Map results = new TreeMap (getStringComparator()); + MobyNamespace[] namespaces = getFullNamespaces(); + for (int i = 0; i < namespaces.length; i++) { + results.put (namespaces[i].getName(), + namespaces[i].getDescription()); } - - /******************************************************************************************************************* - * - * @deprecated Replaced by {@link #getFullNamespaces} that gives more information for the same price. - *

      - ******************************************************************************************************************/ - public Map getNamespaces() throws MobyException { - - Map results = new TreeMap( getStringComparator() ); - MobyNamespace[] namespaces = getFullNamespaces(); - for ( int i = 0; i < namespaces.length; i++ ) { - results.put( namespaces[ i ].getName(), namespaces[ i ].getDescription() ); - } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

            *  <objectNames>
      -     *     <Object name="objectName" lsid="...">
      +     *     <Object name="objectName" lsid="...">
            *            <Description><![CDATA[free text description here]]></Description>
            *     </Object>
            *          ...
            *          ...
            *  </objectNames>
            * 
      - ******************************************************************************************************************/ - public Map getDataTypeNames() throws MobyException { - String result = getDataTypeNamesAsXML(); - return createDataTypeNamesFromXML( result, true ); + *************************************************************************/ + public Map getDataTypeNames() + throws MobyException { + String result = getDataTypeNamesAsXML(); + return createDataTypeNamesFromXML (result, true); } // - protected String getDataTypeNamesAsXML() throws MobyException { - return ( String ) doCall( "retrieveObjectNames", new Object[] {} ); + protected String getDataTypeNamesAsXML() + throws MobyException { + return (String)doCall ("retrieveObjectNames", + new Object[] {}); } // if onlyNames == true - // Map: data type name -> description (String) + // Map: data type name -> description (String) // else - // Map: data type name -> MobyDataType[] - // (filled with name, description, and lsid) - protected Map createDataTypeNamesFromXML( String result, boolean onlyNames ) throws MobyException { - - // parse returned XML - Map results = new TreeMap( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Object" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String name = elem.getAttribute( "name" ); - if ( name == null ) continue; // ignore no-named data types - String desc = ""; - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "Description" ) ) { - desc = getFirstValue( children.item( j ) ); - break; - } - } - if ( onlyNames ) { - results.put( name, desc ); - } - else { - MobyDataType dt = new MobyDataType( name ); - dt.setDescription( desc ); - dt.setLSID( elem.getAttribute( "lsid" ) ); - results.put( name, dt ); - } + // Map: data type name -> MobyDataType[] + // (filled with name, description, and lsid) + protected Map createDataTypeNamesFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Object"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + if (name == null) + continue; // ignore no-named data types + String desc = ""; + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("Description")) { + desc = getFirstValue (children.item (j)); + break; } - return results; + } + if (onlyNames) { + results.put (name, desc); + } else { + MobyDataType dt = new MobyDataType (name); + dt.setDescription (desc); + dt.setLSID (elem.getAttribute ("lsid")); + results.put (name, dt); + } + } + return results; } - /******************************************************************************************************************* + + /************************************************************************** * Parses and imports the following XML. An example: - * + * *
            * <retrieveObjectDefinition>
      -     *   <objectType lsid="...">go_term</objectType>
      +     *   <objectType lsid="...">go_term</objectType>
            *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
            *   <authURI>http://www.illuminae.com</authURI>
            *   <contactEmail>markw at illuminae.com</contactEmail>
      @@ -1006,448 +1071,529 @@
            *   </Relationship>
            * </retrieveObjectDefinition>
            * 
      - ******************************************************************************************************************/ - public MobyDataType getDataType( String dataTypeName ) throws MobyException, NoSuccessException { - - String result = getDataTypeAsXML( dataTypeName ); - return createDataTypeFromXML( result, dataTypeName ); - } - - public MobyDataType[] getDataTypes() throws MobyException, NoSuccessException { - Map< String, String > datatypeMap = getDataTypeNames(); - MobyDataType[] datatypes = new MobyDataType[ datatypeMap.size() ]; - int i = 0; - for ( String dataTypeName : datatypeMap.keySet() ) { - datatypes[ i++ ] = getDataType( dataTypeName ); - } - return datatypes; - } - - protected String getDataTypeAsXML( String dataTypeName ) throws MobyException, NoSuccessException { - - return ( String ) doCall( "retrieveObjectDefinition", new Object[] { "" - + "" + dataTypeName + "" + "" } ); - } - - protected MobyDataType createDataTypeFromXML( String xmlSource, String dataTypeName ) throws MobyException, - NoSuccessException { - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( xmlSource.getBytes() ) ); - NodeList list = document.getElementsByTagName( "retrieveObjectDefinition" ); - if ( list == null || list.getLength() == 0 ) - throw new NoSuccessException( "Data Type name was not found.", dataTypeName ); - MobyDataType data = null; - Element elem = ( Element ) list.item( 0 ); - NodeList children = elem.getChildNodes(); - - // first find the "real" (LSID-ized) data type name - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "objectType" ) ) { - data = new MobyDataType( getFirstValue( children.item( j ) ) ); - data.setLSID( ( ( Element ) children.item( j ) ).getAttribute( "lsid" ) ); - break; - } - } - - // if not found (unprobable) use the name given by the caller - if ( data == null ) data = new MobyDataType( dataTypeName ); - - // now fill the data type object with the rest of attributes - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "Description" ) ) { - data.setDescription( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "authURI" ) ) { - data.setAuthority( getFirstValue( children.item( j ) ) ); + *************************************************************************/ + public MobyDataType getDataType (String dataTypeName) + throws MobyException, NoSuccessException { + + String result = getDataTypeAsXML (dataTypeName); + return createDataTypeFromXML (result, dataTypeName); + } + + public MobyDataType[] getDataTypes() + throws MobyException, NoSuccessException { + Map datatypeMap = getDataTypeNames(); + MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; + int i = 0; + for(String dataTypeName: datatypeMap.keySet()){ + datatypes[i++] = getDataType(dataTypeName); + } + return datatypes; + } + + protected String getDataTypeAsXML (String dataTypeName) + throws MobyException, NoSuccessException { + + return (String)doCall ("retrieveObjectDefinition", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + }); + } + + protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) + throws MobyException, NoSuccessException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); + NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); + if (list == null || list.getLength() == 0) + throw new NoSuccessException ("Data Type name was not found.", + dataTypeName); + MobyDataType data = null; + Element elem = (Element)list.item (0); + NodeList children = elem.getChildNodes(); + + // first find the "real" (LSID-ized) data type name + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("objectType")) { + data = new MobyDataType (getFirstValue (children.item (j))); + data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); + break; + } + } + + // if not found (unprobable) use the name given by the caller + if (data == null) + data = new MobyDataType (dataTypeName); + + // now fill the data type object with the rest of attributes + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + data.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("authURI")) { + data.setAuthority (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + data.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Relationship")) { + String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); + if (relationshipType.endsWith ("isa")) { + + NodeList parents = children.item (j).getChildNodes(); + for (int k = 0; k < parents.getLength(); k++) { + if (parents.item (k).getNodeName().equals ("objectType")) { + data.addParentName (getFirstValue (parents.item (k))); + } + } + } else if (relationshipType.endsWith ("hasa")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + getFirstValue (belows.item (k)), + Central.iHASA ); + } + } + } else if (relationshipType.endsWith ("has")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + belows.item (k).getFirstChild().getNodeValue(), + Central.iHAS ); } - else if ( nodeName.equals( "contactEmail" ) ) { - data.setEmailContact( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "Relationship" ) ) { - String relationshipType = ( ( Element ) children.item( j ) ).getAttribute( "relationshipType" ); - if ( relationshipType.endsWith( "isa" ) ) { - - NodeList parents = children.item( j ).getChildNodes(); - for ( int k = 0; k < parents.getLength(); k++ ) { - if ( parents.item( k ).getNodeName().equals( "objectType" ) ) { - data.addParentName( getFirstValue( parents.item( k ) ) ); - } - } - } - else if ( relationshipType.endsWith( "hasa" ) ) { - - NodeList belows = children.item( j ).getChildNodes(); - for ( int k = 0; k < belows.getLength(); k++ ) { - if ( belows.item( k ).getNodeName().equals( "objectType" ) ) { - data.addChild( ( ( Element ) belows.item( k ) ).getAttribute( "articleName" ), - getFirstValue( belows.item( k ) ), Central.iHASA ); - } - } - } - else if ( relationshipType.endsWith( "has" ) ) { - - NodeList belows = children.item( j ).getChildNodes(); - for ( int k = 0; k < belows.getLength(); k++ ) { - if ( belows.item( k ).getNodeName().equals( "objectType" ) ) { - data.addChild( ( ( Element ) belows.item( k ) ).getAttribute( "articleName" ), belows.item( - k ).getFirstChild().getNodeValue(), Central.iHAS ); - } - } - } } } - return data; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getServiceWSDL( String serviceName ) throws MobyException, NoSuccessException { - - Map names = getServiceNames(); - - for ( Iterator it = names.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = ( Map.Entry ) it.next(); - if ( ( ( String ) entry.getKey() ).equals( serviceName ) ) - return getServiceWSDL( serviceName, ( String ) entry.getValue() ); - } - - throw new NoSuccessException( "Service not found.", serviceName ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getServiceWSDL( String serviceName, String authority ) throws MobyException, NoSuccessException { - - String cacheId = "getServiceWSDL" + serviceName + ":" + authority; - String cachedResults = ( String ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "retrieveService", - new Object[] { "" + "" + "" } ); - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - Element service = document.getDocumentElement(); - Node wsdl = service.getFirstChild(); - if ( wsdl == null ) - throw new NoSuccessException( "Service not found OR WSDL is not available.", serviceName + " (" + authority - + ")" ); - - String results = wsdl.getNodeValue(); - setContents( cacheId, results ); - return results; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterDataTypeXML( MobyDataType dataType ) { - - // build the ISA tag (expressing hierarchy of data types) - String[] names = dataType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < names.length; i++ ) { - buf.append( "" ); - buf.append( names[ i ] ); - buf.append( "" ); - buf.append( "\n" ); - } - - // build the HASA/HAS tags (expressing containments of data types) - MobyRelationship[] children = dataType.getChildren(); - StringBuffer buf2 = new StringBuffer(); // for HASA - StringBuffer buf3 = new StringBuffer(); // for HAS - for ( int i = 0; i < children.length; i++ ) { - if ( children[ i ].getRelationshipType() == Central.iHASA ) { - buf2.append( "" ); - buf2.append( children[ i ].getDataTypeName() ); - buf2.append( "" ); - } - else if ( children[ i ].getRelationshipType() == Central.iHAS ) { - buf3.append( "" ); - buf3.append( children[ i ].getDataTypeName() ); - buf3.append( "" ); - } } - - return "" + "" + dataType.getName() + "" - + "" + "" - + "" + new String( buf ) + "" - + "" + new String( buf2 ) + "" - + "" + new String( buf3 ) + "" + "" - + dataType.getAuthority() + "" + "" + dataType.getEmailContact() - + "" + ""; } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerDataType( MobyDataType dataType ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerObjectClass", new Object[] { getRegisterDataTypeXML( dataType ) } ); - dataType.setId( checkRegistration( result, dataType )[ 0 ] ); + return data; + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName) + throws MobyException, NoSuccessException { + + Map names = getServiceNames(); + + for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + if ( ((String)entry.getKey()).equals (serviceName) ) + return getServiceWSDL (serviceName, (String)entry.getValue()); + } + + throw new NoSuccessException ("Service not found.", serviceName); + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName, String authority) + throws MobyException, NoSuccessException { + + String cacheId = "getServiceWSDL" + serviceName + ":" + authority; + String cachedResults = (String)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("retrieveService", + new Object[] { + "" + + "" + + "" + }); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + Element service = document.getDocumentElement(); + Node wsdl = service.getFirstChild(); + if (wsdl == null) + throw new NoSuccessException ("Service not found OR WSDL is not available.", + serviceName + " (" + authority + ")"); + + String results = wsdl.getNodeValue(); + setContents (cacheId, results); + return results; + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterDataTypeXML (MobyDataType dataType) { + + // build the ISA tag (expressing hierarchy of data types) + String[] names = dataType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + // build the HASA/HAS tags (expressing containments of data types) + MobyRelationship[] children = dataType.getChildren(); + StringBuffer buf2 = new StringBuffer(); // for HASA + StringBuffer buf3 = new StringBuffer(); // for HAS + for (int i = 0; i < children.length; i++) { + if (children[i].getRelationshipType() == Central.iHASA) { + buf2.append (""); + buf2.append (children[i].getDataTypeName()); + buf2.append (""); + } else if (children[i].getRelationshipType() == Central.iHAS) { + buf3.append (""); + buf3.append (children[i].getDataTypeName()); + buf3.append (""); + } + } + + return + "" + + "" + dataType.getName() + "" + + "" + + "" + + "" + new String (buf) + + "" + + "" + new String (buf2) + + "" + + "" + new String (buf3) + + "" + + "" + dataType.getAuthority() + "" + + "" + dataType.getEmailContact() + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerObjectClass", + new Object[] { getRegisterDataTypeXML (dataType) }); + dataType.setId (checkRegistration (result, dataType)[0]); } - /******************************************************************************************************************* + /************************************************************************* * B - ******************************************************************************************************************/ - public void unregisterDataType( MobyDataType dataType ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterObjectClass", new Object[] { "" - + "" + dataType.getName() + "" + "" } ); - checkRegistration( result, dataType ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterServiceTypeXML( MobyServiceType serviceType ) { - - // build the ISA tag (expressing hierarchy of service types) - String[] names = serviceType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < names.length; i++ ) { - buf.append( "" ); - buf.append( names[ i ] ); - buf.append( "" ); - buf.append( "\n" ); - } - - return "" + "" + serviceType.getName() + "" + "" - + serviceType.getEmailContact() + "" + "" + serviceType.getAuthority() - + "" + "" + "" - + "" + new String( buf ) + "" - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerServiceType( MobyServiceType serviceType ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerServiceType", - new Object[] { getRegisterServiceTypeXML( serviceType ) } ); - serviceType.setId( checkRegistration( result, serviceType )[ 0 ] ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterServiceType( MobyServiceType serviceType ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterServiceType", new Object[] { "" - + "" + serviceType.getName() + "" + "" } ); - checkRegistration( result, serviceType ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterNamespaceXML( MobyNamespace namespace ) { - return "" + "" + namespace.getName() + "" + "" - + namespace.getEmailContact() + "" + "" + namespace.getAuthority() - + "" + "" + "" - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerNamespace( MobyNamespace namespace ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "registerNamespace", new Object[] { getRegisterNamespaceXML( namespace ) } ); - namespace.setId( checkRegistration( result, namespace )[ 0 ] ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterNamespace( MobyNamespace namespace ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterNamespace", new Object[] { "" - + "" + namespace.getName() + "" + "" } ); - checkRegistration( result, namespace ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterServiceXML( MobyService service ) { - return "" + "" + service.getCategory() + "" + "" - + service.getName() + "" + "" + service.getType() + "" - + "" + ( service.getLSID() == null ? "" : service.getLSID().trim() ) + "" - + "" + service.getAuthority() + "" + "" - + escapeXML( service.getSignatureURL() ) + "" + "" + escapeXML( service.getURL() ) - + "" + "" + service.getEmailContact() + "" - + "" + ( service.isAuthoritative() ? "1" : "0" ) + "" - + "" + "" - + buildPrimaryInputTag( service ) + buildSecondaryInputTag( service ) + buildOutputTag( service ) - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerService( MobyService service ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerService", new Object[] { getRegisterServiceXML( service ) } ); - String[] registered = checkRegistration( result, service ); - service.setId( registered[ 0 ] ); - service.setRDF( registered[ 1 ] ); - String pathToRDF = service.getPathToRDF(); - if ( !pathToRDF.equals( "" ) ) { - File fileRDF = new File( pathToRDF ); - try { - PrintStream fileout = new PrintStream( new FileOutputStream( fileRDF ) ); - fileout.println( registered[ 1 ] ); - fileout.close(); - } - catch ( IOException e ) { - StringBuffer buf = new StringBuffer( 100 ); - buf.append( "Failed to save RDF in '" ); - buf.append( fileRDF.getAbsolutePath() + "'. " ); - buf.append( e.toString() ); - try { - File tmpFile = File.createTempFile( service.getName() + "-", ".rdf" ); - PrintStream fileout = new PrintStream( new FileOutputStream( tmpFile ) ); - fileout.println( registered[ 1 ] ); - fileout.close(); - buf.append( "\nReturned RDF file was therefore stored in: " ); - buf.append( tmpFile.getAbsolutePath() ); - } - catch ( IOException e2 ) { - buf.append( "\nEven saving in a temporary file failed: " ); - buf.append( e2.toString() ); - } - throw new MobyException( buf.toString() ); - } - } - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterService( MobyService service ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterService", new Object[] { "" + "" - + service.getAuthority() + "" + "" + service.getName() + "" - + "" } ); - checkRegistration( result, service ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( String serviceType ) throws MobyException { - if ( serviceType == null ) return new MobyService[] {}; - MobyService pattern = new MobyService( "dummy" ); - pattern.setCategory( "" ); - pattern.setType( serviceType ); - return findService( pattern, null ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( String[] keywords ) throws MobyException { - if ( keywords == null ) return new MobyService[] {}; - return findService( null, keywords ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern ) throws MobyException { - if ( pattern == null ) return new MobyService[] {}; - return findService( pattern, null ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern, String[] keywords ) throws MobyException { - return findService( pattern, keywords, true, true ); + *************************************************************************/ + public void unregisterDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterObjectClass", + new Object[] { + "" + + "" + dataType.getName() + "" + + "" + }); + checkRegistration (result, dataType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceTypeXML (MobyServiceType serviceType) { + + // build the ISA tag (expressing hierarchy of service types) + String[] names = serviceType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + return + "" + + "" + serviceType.getName() + "" + + "" + serviceType.getEmailContact() + "" + + "" + serviceType.getAuthority() + "" + + "" + + "" + + "" + new String (buf) + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerServiceType", + new Object[] { getRegisterServiceTypeXML (serviceType) }); + serviceType.setId (checkRegistration (result, serviceType)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterServiceType", + new Object[] { + "" + + "" + serviceType.getName() + "" + + "" + }); + checkRegistration (result, serviceType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterNamespaceXML (MobyNamespace namespace) { + return + "" + + "" + namespace.getName() + "" + + "" + namespace.getEmailContact() + "" + + "" + namespace.getAuthority() + "" + + "" + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("registerNamespace", + new Object[] { getRegisterNamespaceXML (namespace) }); + namespace.setId (checkRegistration (result, namespace)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterNamespace", + new Object[] { + "" + + "" + namespace.getName() + "" + + "" + }); + checkRegistration (result, namespace); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceXML (MobyService service) { + return + "" + + "" + service.getCategory() + "" + + "" + service.getName() + "" + + "" + service.getType() + "" + + "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + + "" + service.getAuthority() + "" + + "" + escapeXML (service.getSignatureURL()) + "" + + "" + escapeXML (service.getURL()) + "" + + "" + service.getEmailContact() + "" + + "" + (service.isAuthoritative() ? "1" : "0") + "" + + "" + + "" + + buildPrimaryInputTag (service) + + buildSecondaryInputTag (service) + + buildOutputTag (service) + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerService", + new Object[] { getRegisterServiceXML (service) }); + String[] registered = checkRegistration (result, service); + service.setId (registered [0]); + service.setRDF (registered [1]); + String pathToRDF = service.getPathToRDF(); + if ( ! pathToRDF.equals ("") ) { + File fileRDF = new File (pathToRDF); + try { + PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); + fileout.println (registered [1]); + fileout.close(); + } catch (IOException e) { + StringBuffer buf = new StringBuffer (100); + buf.append ("Failed to save RDF in '"); + buf.append (fileRDF.getAbsolutePath() + "'. "); + buf.append (e.toString()); + try { + File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); + PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); + fileout.println (registered [1]); + fileout.close(); + buf.append ("\nReturned RDF file was therefore stored in: "); + buf.append (tmpFile.getAbsolutePath()); + } catch (IOException e2) { + buf.append ("\nEven saving in a temporary file failed: "); + buf.append (e2.toString()); + } + throw new MobyException (buf.toString()); + } + } + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterService", + new Object[] { + "" + + "" + service.getAuthority() + "" + + "" + service.getName() + "" + + "" + }); + checkRegistration (result, service); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String serviceType) + throws MobyException { + if (serviceType == null) + return new MobyService[] {}; + MobyService pattern = new MobyService ("dummy"); + pattern.setCategory (""); + pattern.setType (serviceType); + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String[] keywords) + throws MobyException { + if (keywords == null) + return new MobyService[] {}; + return findService (null, keywords); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern) + throws MobyException { + if (pattern == null) + return new MobyService[] {}; + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords) + throws MobyException { + return findService (pattern, keywords, true, true); } - /******************************************************************************************************************* + /************************************************************************** * All 'findService' methods end up here. - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern, String[] keywords, boolean includeChildrenServiceTypes, - boolean includeParentDataTypes ) throws MobyException { - if ( pattern == null ) { - pattern = new MobyService( "dummy" ); - pattern.setCategory( "" ); - } + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + if (pattern == null) { + pattern = new MobyService ("dummy"); + pattern.setCategory (""); + } - String result = getServicesAsXML( pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes ); - MobyService[] services = extractServices( result ); - return services; + String result = + getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); + MobyService[] services = extractServices (result); + return services; } // ...actually all 'findService' methods end up here - protected String getServicesAsXML( MobyService pattern, String[] keywords, boolean includeChildrenServiceTypes, - boolean includeParentDataTypes ) throws MobyException { - String[] query = new String[] { "" - + buildQueryObject( pattern, keywords, includeParentDataTypes, includeChildrenServiceTypes, false ) - + "" }; - return ( String ) doCall( "findService", query ); + protected String getServicesAsXML (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + String[] query = new String[] { + "" + + buildQueryObject (pattern, keywords, + includeParentDataTypes, + includeChildrenServiceTypes, + false) + + "" + }; + return (String)doCall ("findService", query); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String call( String methodName, String inputXML ) throws MobyException { - Object result; - if ( inputXML == null || inputXML.equals( "" ) ) - result = doCall( methodName, new Object[] {} ); - else - result = doCall( methodName, new Object[] { inputXML } ); - return ( String ) result; + /************************************************************************** + * + *************************************************************************/ + public String call (String methodName, String inputXML) + throws MobyException { + Object result; + if (inputXML == null || inputXML.equals ("")) + result = doCall (methodName, new Object[] { }); + else + result = doCall (methodName, new Object[] { inputXML }); + return (String)result; + } + + /************************************************************************** + * + *************************************************************************/ + protected static String resultToString (Object result) + throws MobyException { + if (result == null) + throw new MobyException ("Returned result is null."); + if (result instanceof String) + return (String)result; + if (result instanceof String[]) { + String[] tmp = (String[])result; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < tmp.length; i++) + buf.append (tmp[i]); + return new String (buf); } + if (result instanceof byte[]) + return new String ((byte[])result); - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected static String resultToString( Object result ) throws MobyException { - if ( result == null ) throw new MobyException( "Returned result is null." ); - if ( result instanceof String ) return ( String ) result; - if ( result instanceof String[] ) { - String[] tmp = ( String[] ) result; - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < tmp.length; i++ ) - buf.append( tmp[ i ] ); - return new String( buf ); - } - if ( result instanceof byte[] ) return new String( ( byte[] ) result ); - - throw new MobyException( "Unknown type of result: " + result.getClass().getName() ); + throw new MobyException ("Unknown type of result: " + result.getClass().getName()); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public boolean setDebug( boolean enabled ) { - boolean oldMode = debug; - debug = enabled; - return oldMode; + /************************************************************************** + * + *************************************************************************/ + public boolean setDebug (boolean enabled) { + boolean oldMode = debug; + debug = enabled; + return oldMode; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
            * <Relationships>
            *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
      @@ -1456,45 +1602,55 @@
            *   </Relationship>
            * </Relationships>
            * 
      - ******************************************************************************************************************/ - public String[] getServiceTypeRelationships( String serviceTypeName, boolean expand ) throws MobyException { - String result = getServiceTypeRelationshipsAsXML( serviceTypeName, expand ); - return createServiceTypeRelationshipsFromXML( result ); + *************************************************************************/ + public String[] getServiceTypeRelationships (String serviceTypeName, + boolean expand) + throws MobyException { + String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); + return createServiceTypeRelationshipsFromXML (result); } // - protected String getServiceTypeRelationshipsAsXML( String serviceTypeName, boolean expand ) throws MobyException { - return ( String ) doCall( "Relationships", new Object[] { "" + "" + serviceTypeName - + "" + "" + Central.ISA + "" - + "" + ( expand ? "1" : "0" ) + "" + "" } ); + protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, + boolean expand) + throws MobyException { + return + (String)doCall ("Relationships", + new Object[] { + "" + + "" + serviceTypeName + "" + + "" + Central.ISA + "" + + "" + (expand ? "1" : "0") + "" + + "" + }); } // - protected String[] createServiceTypeRelationshipsFromXML( String result ) throws MobyException { + protected String[] createServiceTypeRelationshipsFromXML (String result) + throws MobyException { - // parse returned XML - Vector< String > v = new Vector< String >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "serviceType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("serviceType")) { + v.addElement (getFirstValue (children.item (j))); + } } - String[] results = new String[ v.size() ]; - v.copyInto( results ); - return results; + } + String[] results = new String [v.size()]; + v.copyInto (results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
      -     * lt;Relationships>
      +     *<Relationships>
            *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
            *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
            *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
      @@ -1503,411 +1659,431 @@
            *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
            *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
            *  </Relationship>
      -     * lt;/Relationships>
      +     *</Relationships>
            * 
      - * - * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an attributes 'lsid' and 'articleName' in - * <objectType> element. - ******************************************************************************************************************/ - public Map getDataTypeRelationships( String dataTypeName ) throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName; - Map cachedResults = ( Map ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "Relationships", new Object[] { "" + "" - + dataTypeName + "" + "" + Central.ISA + "" - + "" + Central.HASA + "" + "" + Central.HAS - + "" + "1" + "" } ); - - // parse returned XML - Map results = new HashMap(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String relType = elem.getAttribute( "relationshipType" ); - NodeList children = elem.getChildNodes(); - Vector< String > v = new Vector< String >(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "objectType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } - String[] names = new String[ v.size() ]; - v.copyInto( names ); - results.put( relType, names ); + * + * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an + * attributes 'lsid' and 'articleName' in <objectType> element. + *************************************************************************/ + public Map getDataTypeRelationships (String dataTypeName) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName; + Map cachedResults = (Map)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + Central.ISA + "" + + "" + Central.HASA + "" + + "" + Central.HAS + "" + + "1" + + "" + }); + + // parse returned XML + Map results = new HashMap(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String relType = elem.getAttribute ("relationshipType"); + NodeList children = elem.getChildNodes(); + Vector v = new Vector(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } } + String[] names = new String [v.size()]; + v.copyInto (names); + results.put (relType, names); + } - setContents( cacheId, results ); - return results; + setContents (cacheId, results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
      -     * lt;Relationships>
      +     *<Relationships>
            *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
            *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
            *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
            *  </Relationship>
      -     * lt;/Relationships>
      +     *</Relationships>
            * 
      - ******************************************************************************************************************/ - public String[] getDataTypeRelationships( String dataTypeName, String relationshipType ) throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; - String[] cachedResults = ( String[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "Relationships", new Object[] { "" + "" - + dataTypeName + "" + "" + relationshipType + "" - + "1" + "" } ); - - // parse returned XML - Vector< String > v = new Vector< String >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - - // it should always be just one element in this list - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "objectType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } + *************************************************************************/ + public String[] getDataTypeRelationships (String dataTypeName, + String relationshipType) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + relationshipType + "" + + "1" + + "" + }); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + // it should always be just one element in this list + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); } - String[] results = new String[ v.size() ]; - v.copyInto( results ); + } + } + String[] results = new String [v.size()]; + v.copyInto (results); - setContents( cacheId, results ); - return results; + setContents (cacheId, results); + return results; } - // /************************************************************************** - // * - // *************************************************************************/ - // public MobyRelationship[] getRelationships (String dataTypeName) - // throws MobyException { - // return null; - // } +// /************************************************************************** +// * +// *************************************************************************/ +// public MobyRelationship[] getRelationships (String dataTypeName) +// throws MobyException { +// return null; +// } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ + + /************************************************************************** + * + *************************************************************************/ public String getRegistryEndpoint() { - return endpoint.toString(); + return endpoint.toString(); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ + /************************************************************************** + * + *************************************************************************/ public String getRegistryNamespace() { - return uri; + return uri; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
            * <resourceURLs>
      -     *   <Resource name="Service"         url="..." />
      -     *   <Resource name="Object"          url="..." />
      -     *   <Resource name="Namespace"       url="..." />
      -     *   <Resource name="ServiceInstance" url="..." />
      -     *   <Resource name="Full"            url="..." />
      +     *   <Resource name="Service"         url="..." />
      +     *   <Resource name="Object"          url="..." />
      +     *   <Resource name="Namespace"       url="..." />
      +     *   <Resource name="ServiceInstance" url="..." />
      +     *   <Resource name="Full"            url="..." />
            * </resourceURLs>
            * 
      - ******************************************************************************************************************/ - public MobyResourceRef[] getResourceRefs() throws MobyException { - - String cacheId = "retrieveResourceURLs"; - MobyResourceRef[] cachedResults = ( MobyResourceRef[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "retrieveResourceURLs", new Object[] {} ); - - // parse returned XML - Vector< MobyResourceRef > v = new Vector< MobyResourceRef >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Resource" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - try { - v.addElement( new MobyResourceRef( elem.getAttribute( "name" ), new URL( ( String ) elem - .getAttribute( "url" ) ), elem.getAttribute( "type" ) ) ); - } - catch ( MalformedURLException e2 ) { - if ( debug ) System.err.println( "Bad URL: " + elem.getAttribute( "url" ) ); - } + *************************************************************************/ + public MobyResourceRef[] getResourceRefs() + throws MobyException { + + String cacheId = "retrieveResourceURLs"; + MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveResourceURLs", + new Object[] {}); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Resource"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + try { + v.addElement + (new MobyResourceRef (elem.getAttribute ("name"), + new URL ((String)elem.getAttribute ("url")), + elem.getAttribute ("type"))); + } catch (MalformedURLException e2) { + if (debug) + System.err.println ("Bad URL: " + elem.getAttribute ("url")); } + } - MobyResourceRef[] results = new MobyResourceRef[ v.size() ]; - v.copyInto( results ); + MobyResourceRef[] results = new MobyResourceRef [v.size()]; + v.copyInto (results); - // Add this data to the cache in case we get called again - setContents( cacheId, results ); + // Add this data to the cache in case we get called again + setContents (cacheId, results); - return results; + return results; } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public InputStream getResource( String resourceName ) throws MobyException { + /************************************************************************** + * + *************************************************************************/ + public InputStream getResource (String resourceName) + throws MobyException { - MobyResourceRef[] resourceRefs = getResourceRefs(); - for ( int i = 0; i < resourceRefs.length; i++ ) { - if ( resourceName.equalsIgnoreCase( resourceRefs[ i ].getResourceName() ) ) { - return Utils.getInputStream( resourceRefs[ i ].getResourceLocation() ); - } + MobyResourceRef[] resourceRefs = getResourceRefs(); + for (int i = 0; i < resourceRefs.length; i++) { + if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { + return Utils.getInputStream (resourceRefs[i].getResourceLocation()); } - throw new MobyException( "No resource found for '" + resourceName + "'." ); + } + throw new MobyException ("No resource found for '" + resourceName + "'."); } - /******************************************************************************************************************* - * Return a case-insensitive comparator of Strings. It is used to create various TreeMaps where keys are strings. - ******************************************************************************************************************/ + /************************************************************************** + * Return a case-insensitive comparator of Strings. It is used to + * create various TreeMaps where keys are strings. + *************************************************************************/ protected static Comparator getStringComparator() { - return new Comparator() { - public int compare( Object o1, Object o2 ) { - return ( ( String ) o1 ).compareToIgnoreCase( ( String ) o2 ); - } + return new Comparator() { + public int compare (Object o1, Object o2) { + return ((String)o1).compareToIgnoreCase ((String)o2); + } }; } - - // cache URL/URI so we only check once + + // cache URL/URI so we only check once private static String CHECKED_URL = null; private static String CHECKED_URI = null; - + /** - * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared class hierarchy - * that implicitly check the registry will use the same cache. Otherwise, methods such as - * MobyNamespace.getNamespace() must be passed a Central object parameter as well. - * + * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared + * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods + * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. + * * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism */ - public static CentralImpl getDefaultCentral() throws MobyException { - return getDefaultCentral( null ); + public static CentralImpl getDefaultCentral() throws MobyException{ + return getDefaultCentral(null); } - public static CentralImpl getDefaultCentral( Registry reg ) throws MobyException { - if ( reg == null && defaultCentrals.containsKey( "" ) ) { - return defaultCentrals.get( "" ); - } - else if ( reg != null && defaultCentrals.containsKey( reg.getEndpoint() ) ) { - return defaultCentrals.get( reg.getEndpoint() ); - } + public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ + if(reg == null && defaultCentrals.containsKey("")){ + return defaultCentrals.get(""); + } + else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ + return defaultCentrals.get(reg.getEndpoint()); + } - String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - URL resURL = classLoader.getResource( "META-INF/" + CENTRAL_IMPL_RESOURCE_NAME ); - if ( resURL != null ) { - System.err.println( "Loading " + resURL ); - try { - LineNumberReader reader = new LineNumberReader( new InputStreamReader( resURL.openStream() ) ); - for ( String line = reader.readLine(); line != null; line = reader.readLine() ) { - if ( !line.trim().startsWith( "#" ) ) { - className = line.trim(); - break; - } - } - } - catch ( Exception e ) { - logger.log( Level.WARNING, "Error reading " + resURL, e ); + String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); + if(resURL != null){ + System.err.println("Loading "+resURL); + try{ + LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); + for(String line = reader.readLine(); line != null; line = reader.readLine()){ + if(!line.trim().startsWith("#")){ + className = line.trim(); + break; } } - try { - System.err.println( "Central class is " + className ); - Class clazz = Class.forName( className ); - if ( reg == null ) { // should use default nullary c-tor - defaultCentrals.put( "", ( CentralImpl ) clazz.newInstance() ); - } - else { // should have (String endpoint, String namespace) c-tor - for ( Constructor ctor : clazz.getDeclaredConstructors() ) { - Class[] params = ctor.getParameterTypes(); - if ( params.length == 2 && params[ 0 ].getName().equals( "java.lang.String" ) - && params[ 1 ].getName().equals( "java.lang.String" ) ) { - defaultCentrals.put( reg.getEndpoint(), ( CentralImpl ) ctor.newInstance( reg.getEndpoint(), - reg.getNamespace() ) ); - break; - } - } - if ( !defaultCentrals.containsKey( reg.getEndpoint() ) ) { - logger.log( Level.WARNING, "Could not find required (String endpoint, String namespace)" - + "constructor for class " + className ); - } - } + } catch(Exception e){ + logger.log(Level.WARNING, + "Error reading " + resURL, + e); } - catch ( Exception e ) { - logger.log( Level.WARNING, "Could not load class " + className, e ); - if ( reg == null ) { - defaultCentrals.put( "", new CentralImpl() ); // fallback to this class, no caching, etc. - } - else { - defaultCentrals.put( reg.getEndpoint(), new CentralImpl( reg.getEndpoint(), reg.getNamespace() ) ); + } + try{ + System.err.println("Central class is "+className); + Class clazz = Class.forName(className); + if(reg == null){ // should use default nullary c-tor + defaultCentrals.put("", (CentralImpl) clazz.newInstance()); + } + else{ // should have (String endpoint, String namespace) c-tor + for(Constructor ctor: clazz.getDeclaredConstructors()){ + Class[] params = ctor.getParameterTypes(); + if(params.length == 2 && params[0].getName().equals("java.lang.String") && + params[1].getName().equals("java.lang.String") ){ + defaultCentrals.put(reg.getEndpoint(), + (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); + break; } } + if(!defaultCentrals.containsKey(reg.getEndpoint())){ + logger.log(Level.WARNING, + "Could not find required (String endpoint, String namespace)" + + "constructor for class " + className); + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Could not load class " + className, + e); + if(reg == null){ + defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. + } + else{ + defaultCentrals.put(reg.getEndpoint(), + new CentralImpl(reg.getEndpoint(), reg.getNamespace())); + } + } - return defaultCentrals.get( reg == null ? "" : reg.getEndpoint() ); + return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); } /** * - * @return a String representing the Default mobycentral endpoint. If the system property 'moby.check.default' - * exists and is set to true, then the URL http://biomoby.org/mobycentral is queried and the default central - * endpoint is returned, otherwise DEFAULT_ENDPOINT is returned. + * @return a String representing the Default mobycentral endpoint. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central endpoint is returned, otherwise DEFAULT_ENDPOINT + * is returned. */ public static String getDefaultURL() { - boolean check = false; + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + + if (check) { + // return the last checked url if we have done this before + if (CHECKED_URL != null && CHECKED_URL.trim() != "") { + return CHECKED_URL; + } + + // create a HttpClient object + HttpClient client = new HttpClient(); + // set up the Head method + HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); + // do not follow redirects or we will get a 411 error + method.setFollowRedirects(false); + // retry 3 times + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); + // set the user agent ... should probably make this something more reasonable + method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); try { - check = Boolean.getBoolean( "moby.check.default" ); - } - catch ( Exception e ) { - - } + // Execute the method. + int statusCode = client.executeMethod(method); - if ( check ) { - // return the last checked url if we have done this before - if ( CHECKED_URL != null && CHECKED_URL.trim() != "" ) { - return CHECKED_URL; - } - - // create a HttpClient object - HttpClient client = new HttpClient(); - // set up the Head method - HeadMethod method = new HeadMethod( "http://biomoby.org/mobycentral" ); - // do not follow redirects or we will get a 411 error - method.setFollowRedirects( false ); - // retry 3 times - method.getParams().setParameter( HttpMethodParams.RETRY_HANDLER, - new DefaultHttpMethodRetryHandler( 3, false ) ); - // set the user agent ... should probably make this something more reasonable - method.getParams().setParameter( HttpMethodParams.USER_AGENT, "jMoby/1.0" ); + if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { + System.err.println("Method failed: " + + method.getStatusLine()); + } else { try { - // Execute the method. - int statusCode = client.executeMethod( method ); - - if ( statusCode != HttpStatus.SC_MOVED_PERMANENTLY ) { - System.err.println( "Method failed: " + method.getStatusLine() ); - } - else { - try { - String location = method.getResponseHeader( "location" ).getValue(); - CHECKED_URL = location; - try { - CHECKED_URI = "http://" + ( new URL( CHECKED_URL ).getAuthority() ) + "/MOBY/Central"; - } - catch ( MalformedURLException murle ) { - CHECKED_URI = DEFAULT_NAMESPACE; - } - return CHECKED_URL; - } - catch ( NullPointerException npe ) { - return DEFAULT_ENDPOINT; - } - } - } - catch ( HttpException e ) { - System.err.println( "Fatal protocol violation: " + e.getMessage() ); - e.printStackTrace(); - } - catch ( IOException e ) { - System.err.println( "Fatal transport error: " + e.getMessage() ); - e.printStackTrace(); - } - finally { - // Release the connection. - method.releaseConnection(); + String location = method.getResponseHeader("location").getValue(); + CHECKED_URL = location; + try { + CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; + } catch (MalformedURLException murle ) { + CHECKED_URI = DEFAULT_NAMESPACE; } - - } - else { + return CHECKED_URL; + } catch (NullPointerException npe) { return DEFAULT_ENDPOINT; + } } + } catch (HttpException e) { + System.err.println("Fatal protocol violation: " + + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + System.err.println("Fatal transport error: " + e.getMessage()); + e.printStackTrace(); + } finally { + // Release the connection. + method.releaseConnection(); + } + + } else { return DEFAULT_ENDPOINT; } - + return DEFAULT_ENDPOINT; + } + /** * - * @return a String representing the default mobycentral uri. If the system property 'moby.check.default' exists and - * is set to true, then the URL http://biomoby.org/mobycentral is queried and the default central namespace - * is returned, otherwise DEFAULT_NAMESPACE is returned. + * @return a String representing the default mobycentral uri. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central namespace is returned, otherwise DEFAULT_NAMESPACE + * is returned. */ public static String getDefaultURI() { - boolean check = false; - try { - check = Boolean.getBoolean( "moby.check.default" ); - } - catch ( Exception e ) { - - } - if ( check ) { - if ( CHECKED_URI != null && CHECKED_URI.trim() != "" ) { - return CHECKED_URI; - } - // need to check ... - getDefaultURL(); - return CHECKED_URI; - } - else { - return DEFAULT_NAMESPACE; - } - } - - /******************************************************************************************************************* - * Convert non-suitable characters in a XML string into their entity references. - *

      - * + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + if (check) { + if (CHECKED_URI != null && CHECKED_URI.trim() != "") { + return CHECKED_URI; + } + // need to check ... + getDefaultURL(); + return CHECKED_URI; + } else { + return DEFAULT_NAMESPACE; + } + } + /************************************************************************** + * Convert non-suitable characters in a XML string into their + * entity references.

      + * * Adapted from jDom. - * - * @param str - * input to be converted - * @return If there were any non-suitable characters, return a new string with those characters escaped, otherwise - * return the unmodified input string - * - ******************************************************************************************************************/ - public String escapeXML( String str ) { + * + * @param str input to be converted + * @return If there were any non-suitable characters, return a new + * string with those characters escaped, otherwise return the + * unmodified input string + * + *************************************************************************/ + public String escapeXML (String str) { StringBuffer buffer = null; char ch; String entity; - for ( int i = 0; i < str.length(); i++ ) { - ch = str.charAt( i ); - switch ( ch ) { - case '<': - entity = "<"; - break; - case '>': - entity = ">"; - break; - case '&': - entity = "&"; - break; - default: - entity = null; - break; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt (i); + switch (ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; + case '&' : + entity = "&"; + break; + default : + entity = null; + break; } - if ( buffer == null ) { - if ( entity != null ) { + if (buffer == null) { + if (entity != null) { // An entity occurred, so we'll have to use StringBuffer // (allocate room for it plus a few more entities). - buffer = new StringBuffer( str.length() + 20 ); + buffer = new StringBuffer (str.length() + 20); // Copy previous skipped characters and fall through // to pickup current character - buffer.append( str.substring( 0, i ) ); - buffer.append( entity ); - } - } - else { - if ( entity == null ) { - buffer.append( ch ); + buffer.append (str.substring (0, i)); + buffer.append (entity); } - else { - buffer.append( entity ); + } else { + if (entity == null) { + buffer.append (ch); + } else { + buffer.append (entity); } } } @@ -1915,43 +2091,49 @@ // If there were any entities, return the escaped characters // that we put in the StringBuffer. Otherwise, just return // the unmodified input string. - return ( buffer == null ) ? str : buffer.toString(); + return (buffer == null) ? str : buffer.toString(); } - /******************************************************************************************************************* + /************************************************************************* * Format an exception. - ******************************************************************************************************************/ - public static String formatFault( AxisFault e, String endpoint, QName method ) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - formatFault( e, new PrintStream( baos ), endpoint, method ); - return baos.toString(); + *************************************************************************/ + public static String formatFault (AxisFault e, String endpoint, QName method) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + formatFault (e, new PrintStream (baos), endpoint, method); + return baos.toString(); } - /******************************************************************************************************************* + /************************************************************************* * Format an exception. - ******************************************************************************************************************/ - public static void formatFault( AxisFault e, PrintStream out, String endpoint, QName method ) { - - out.println( "===ERROR===" ); - out.println( "Fault details:" ); - // for some obvious errors I do not print all details (with a lenghty trace stack) - String faultString = e.getFaultString(); - if ( ( !faultString.startsWith( "java.net.ConnectException" ) ) - && ( faultString.indexOf( "Could not find class for the service named:" ) == -1 ) ) { - org.w3c.dom.Element[] details = e.getFaultDetails(); - for ( int i = 0; i < details.length; i++ ) { - String s = details[ i ].toString().replaceAll( "<", "<" ); - s = s.replaceAll( ">", ">" ); - out.println( s ); - } - } - out.println( "Fault string: " + faultString ); - out.println( "Fault code: " + e.getFaultCode() ); - out.println( "Fault actor: " + e.getFaultActor() ); - if ( endpoint != null || method != null ) out.println( "When calling:" ); - if ( endpoint != null ) out.println( "\t" + endpoint ); - if ( method != null ) out.println( "\t" + method ); - out.println( "===========" ); + *************************************************************************/ + public static void formatFault (AxisFault e, PrintStream out, + String endpoint, QName method) { + + out.println ("===ERROR==="); + out.println ("Fault details:"); + // for some obvious errors I do not print all details (with a lenghty trace stack) + String faultString = e.getFaultString(); + if ( (! faultString.startsWith ("java.net.ConnectException")) && + (faultString.indexOf ("Could not find class for the service named:") == -1) + ) { + org.w3c.dom.Element[] details = e.getFaultDetails(); + for (int i = 0; i < details.length; i++) { + String s = details[i].toString().replaceAll ("<", "<"); + s = s.replaceAll (">", ">"); + out.println (s); + } + } + out.println ("Fault string: " + faultString); + out.println ("Fault code: " + e.getFaultCode()); + out.println ("Fault actor: " + e.getFaultActor()); + if (endpoint != null || method != null) + out.println ("When calling:"); + if (endpoint != null) + out.println ("\t" + endpoint); + if (method != null) + out.println ("\t" + method); + out.println ("==========="); } + } From kawas at dev.open-bio.org Thu Dec 4 10:31:27 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Thu, 4 Dec 2008 10:31:27 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812041531.mB4FVRR8016254@dev.open-bio.org> kawas Thu Dec 4 10:31:27 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv16218/Perl/MOBY-Server Modified Files: MANIFEST Log Message: added share/cgi/service_unit_tester.pl to the manifest moby-live/Perl/MOBY-Server MANIFEST,1.9,1.10 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST 2008/11/20 19:40:41 1.9 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST 2008/12/04 15:31:26 1.10 @@ -97,6 +97,7 @@ share/cgi/OntologyServer.cgi share/cgi/RESOURCES share/cgi/service_tester.pl +share/cgi/service_unit_tester.pl share/cgi/ServicePingerValidator share/cgi/ValidateService share/config/mobycentral.config.template From groscurt at dev.open-bio.org Wed Dec 17 05:21:57 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 05:21:57 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171021.mBHALvuv005113@dev.open-bio.org> groscurt Wed Dec 17 05:21:57 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test In directory dev.open-bio.org:/tmp/cvs-serv5054/src/main/de/mpg/mpiz_koeln/featureClient/test Modified Files: SimpleSingleCall.java SingleCallWithParameters.java MultiCallWithParameters.java MultiCallByDefinition.java ComplexSingleCall.java SimpleMultiCall.java SingleMultiServiceCall.java Log Message: moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test SimpleSingleCall.java,1.1,1.2 SingleCallWithParameters.java,1.1,1.2 MultiCallWithParameters.java,1.1,1.2 MultiCallByDefinition.java,1.1,1.2 ComplexSingleCall.java,1.1,1.2 SimpleMultiCall.java,1.1,1.2 SingleMultiServiceCall.java,1.1,1.2 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.MobyObject; @@ -19,7 +18,7 @@ client.setTimeout( 45 ); client.addService( "mpiz-koeln.mpg.de", "ID2IDs" ); client.setServiceInputSingleCall( "", "NP_176539.1" ); - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { Collection< MobyObject > collection = mobyServiceResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.AminoAcidSequence; @@ -38,7 +37,7 @@ client.setServiceInputSingleCall( organism, sequence, geneName ); - List< FeatureClientResult > result = client.call(); + Collection < FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { Collection< FASTA_AA > fastas = mobyServiceResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -79,7 +78,7 @@ client.addServiceInputMultiCall( "gene2", organism, sequence, geneName ); // the service is called - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // the map stores for each identifier given the list of results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -34,7 +33,7 @@ client.addServiceInputMultiCall( "AGI_LocusCode", "AT1G12000" ); // call the service, which will be found - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // as we have called the service multiple times we get back for each identifier the returned results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 10:21:56 1.2 @@ -34,7 +34,7 @@ client.setServiceInputSingleCall( sequence ); // start the call and retrieve the results - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult featureClientResult : result ) { // as the service was called once we get back the result for this service call Collection< AminoAcidSequence > sequences = featureClientResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -29,7 +28,7 @@ client.addServiceInputMultiCall( "GO", "0004396" ); // call the service - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // the map stores for each id of the input object a list of results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.MobyService; @@ -27,7 +26,7 @@ client.setServiceInputSingleCall( "AGI_LocusCode", "AT1G12000" ); // call the service - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // you can get which service returned the current result From groscurt at dev.open-bio.org Wed Dec 17 09:07:17 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:07:17 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171407.mBHE7H6U005665@dev.open-bio.org> groscurt Wed Dec 17 09:07:16 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared In directory dev.open-bio.org:/tmp/cvs-serv5630/src/main/org/biomoby/shared Modified Files: MobyService.java Log Message: added hashCode method, based on the uniquename as used in the equals method moby-live/Java/src/main/org/biomoby/shared MobyService.java,1.25,1.26 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java 2008/10/21 16:38:44 1.25 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java 2008/12/17 14:07:16 1.26 @@ -102,6 +102,10 @@ if (obj == null) return false; return getUniqueName().equals ( ((MobyService)obj).getUniqueName() ); } + + public int hashCode() { + return getUniqueName().hashCode(); + } /************************************************************************** * Default constructor. From groscurt at dev.open-bio.org Wed Dec 17 09:09:00 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:09:00 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171409.mBHE90wZ005705@dev.open-bio.org> groscurt Wed Dec 17 09:09:00 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv5670/src/main/org/biomoby/client Modified Files: MobyServiceLocator.java Log Message: javadoc had a warning... moby-live/Java/src/main/org/biomoby/client MobyServiceLocator.java,1.5,1.6 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/03 15:21:13 1.5 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/17 14:09:00 1.6 @@ -168,7 +168,7 @@ /*************************************************** * Returns true if the user AND the password is set - * @return + * @return if authentication shall be used ***************************************************/ public boolean hasAuthentication() { return user != null && password != null; From groscurt at dev.open-bio.org Wed Dec 17 09:09:54 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:09:54 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171409.mBHE9sdL005791@dev.open-bio.org> groscurt Wed Dec 17 09:09:54 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test In directory dev.open-bio.org:/tmp/cvs-serv5728/src/main/de/mpg/mpiz_koeln/featureClient/test Modified Files: SingleCallDefinition.java SingleCallWithParameters.java ComplexSingleCall.java SingleMultiServiceCall.java MultiCallWithParameters.java SimpleSingleCall.java SimpleMultiCall.java MultiCallByDefinition.java Log Message: minor changes moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test SingleCallDefinition.java,1.1,1.2 SingleCallWithParameters.java,1.2,1.3 ComplexSingleCall.java,1.2,1.3 SingleMultiServiceCall.java,1.2,1.3 MultiCallWithParameters.java,1.2,1.3 SimpleSingleCall.java,1.2,1.3 SimpleMultiCall.java,1.2,1.3 MultiCallByDefinition.java,1.2,1.3 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java 2008/12/17 14:09:54 1.2 @@ -9,14 +9,14 @@ import de.mpg.mpiz_koeln.featureClient.FeatureClientException; import de.mpg.mpiz_koeln.featureClient.FeatureClientResult; -public class SingleCallDefinition { +class SingleCallDefinition { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.addOutput( "Object", "PMID" ); client.setTimeout( 45 ); client.add2Filter( "Locus2GeneAliases", "getCor", "getGeneticElementNameByFreeText", "getGoTermAssociations", "getConservedDomainLabelFromDomainId", "ExplodeOutCrossReferences" ); - client.setServiceInputSingleCall( "", "Q9SZW4" ); + client.setSingleCallInput( "", "Q9SZW4" ); Collection< FeatureClientResult > collection = client.call(); for ( FeatureClientResult mobyServiceResult : collection ) { =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ import de.mpg.mpiz_koeln.featureClient.FeatureClientException; import de.mpg.mpiz_koeln.featureClient.FeatureClientResult; -public class SingleCallWithParameters { +class SingleCallWithParameters { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 120 ); @@ -35,7 +35,7 @@ geneName.setId( "my_gene" ); geneName.setName( "gene_name" ); - client.setServiceInputSingleCall( organism, sequence, geneName ); + client.setSingleCallInput( organism, sequence, geneName ); Collection < FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 14:09:54 1.3 @@ -2,7 +2,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.AminoAcidSequence; @@ -18,7 +17,7 @@ * This examples shows how to use the client to call a web service once which consumes a complex data type, such as * AminoAcidSequence. */ -public class ComplexSingleCall { +class ComplexSingleCall { public static void main(String[] args) throws MobyException, FeatureClientException { FeatureClient client = new FeatureClient(); // timeout of the calls is set to 45 seconds @@ -31,7 +30,7 @@ sequence.set_SequenceString( new MobyString( "MQPVKVYADRRSQPSRAVIIFCRVNQIDFEEVTVDLFKSQHLTPEFRKVNPMGQVPAIVDGR" ) ); sequence.set_Length( new MobyInteger( 50 ) ); // set the input to the client - client.setServiceInputSingleCall( sequence ); + client.setSingleCallInput( sequence ); // start the call and retrieve the results Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ /** * This example shows how to call more service one with one input. */ -public class SingleMultiServiceCall { +class SingleMultiServiceCall { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 30 ); @@ -23,7 +23,7 @@ client.addService( "Locus2Publications" ); // set the input of the service - client.setServiceInputSingleCall( "AGI_LocusCode", "AT1G12000" ); + client.setSingleCallInput( "AGI_LocusCode", "AT1G12000" ); // call the service Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 14:09:54 1.3 @@ -18,7 +18,7 @@ * This example shows how to call a service multiple times which consumes more than one input. It also shows the mixture * of a simple object input and a complex data type input. */ -public class MultiCallWithParameters { +class MultiCallWithParameters { public static void main( String[] args ) throws MobyException, FeatureClientException { FeatureClient client = new FeatureClient(); // the service might take longer, so we set the timeout to 120 seconds @@ -55,7 +55,7 @@ // adds the inputs to the client and give it an identifier, so that you are able to distinguish the several // calls later. This identifier is completely free to choice ! - client.addServiceInputMultiCall( "gene1", organism, sequence, geneName ); + client.addMultipleCallInput( "gene1", organism, sequence, geneName ); // we want to call the same service a second time so we build again some input values organism = new MobyObject(); @@ -75,7 +75,7 @@ geneName.setName( "gene_name" ); // adds the inputs to the client for the second call with a different identifier as before - client.addServiceInputMultiCall( "gene2", organism, sequence, geneName ); + client.addMultipleCallInput( "gene2", organism, sequence, geneName ); // the service is called Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 14:09:54 1.3 @@ -12,12 +12,12 @@ /** * This example shows how to call a service once with a simple object input. */ -public class SimpleSingleCall { +class SimpleSingleCall { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 45 ); client.addService( "mpiz-koeln.mpg.de", "ID2IDs" ); - client.setServiceInputSingleCall( "", "NP_176539.1" ); + client.setSingleCallInput( "", "NP_176539.1" ); Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ /** * This example shows how to call a web service multiple times with a simple object input. */ -public class SimpleMultiCall { +class SimpleMultiCall { public static void main( String[] args ) throws MobyException, FeatureClientException { // the client queries the default central if no given otherwise FeatureClient client = new FeatureClient(); @@ -23,9 +23,9 @@ client.addService( "mpiz-koeln.mpg.de", "get_go_information_by_go_term" ); // the three different inputs for the three service calls - client.addServiceInputMultiCall( "GO", "0044408" ); - client.addServiceInputMultiCall( "GO", "0020015" ); - client.addServiceInputMultiCall( "GO", "0004396" ); + client.addMultipleCallInput( "GO", "0044408" ); + client.addMultipleCallInput( "GO", "0020015" ); + client.addMultipleCallInput( "GO", "0004396" ); // call the service Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 14:09:54 1.3 @@ -18,7 +18,7 @@ * * It also shows how to filter out services or authorities which shall be not called at all. */ -public class MultiCallByDefinition { +class MultiCallByDefinition { public static void main( String[] args ) throws MobyException, FeatureClientException { // create a client to the default moby central in calgary with a timeout of 30 seconds FeatureClient client = new FeatureClient(); @@ -28,9 +28,9 @@ // exclude services identified by service name or authority client.add2Filter( "Locus2GeneAliases", "getCor", "bioinfo.icapture.ubc.ca" ); // input for the first call -> it also defines now we search for service which consumes an AGI code - client.addServiceInputMultiCall( "AGI_LocusCode", "AT4G30110" ); + client.addMultipleCallInput( "AGI_LocusCode", "AT4G30110" ); // input for the second call - client.addServiceInputMultiCall( "AGI_LocusCode", "AT1G12000" ); + client.addMultipleCallInput( "AGI_LocusCode", "AT1G12000" ); // call the service, which will be found Collection< FeatureClientResult > result = client.call(); From kawas at dev.open-bio.org Tue Dec 2 18:53:11 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:53:11 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021853.mB2IrBM9006660@dev.open-bio.org> kawas Tue Dec 2 13:53:11 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6624/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: added XML::SemanticCompare to the makefile (used by MobyUnitTest.pm) moby-live/Perl/MOBY-Server Makefile.PL,1.10,1.11 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/11/17 15:25:10 1.10 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:53:11 1.11 @@ -29,6 +29,7 @@ requires 'DBD::mysql' => '0.01'; # used in MobyUnitTest requires 'XML::Simple' => '2.18'; + requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires requires 'WSRF::Lite' => '0.8.2.3'; From kawas at dev.open-bio.org Tue Dec 2 18:53:46 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:53:46 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021853.mB2Irkas006720@dev.open-bio.org> kawas Tue Dec 2 13:53:46 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client In directory dev.open-bio.org:/tmp/cvs-serv6685/Perl/MOBY-Server/lib/MOBY/Client Modified Files: MobyUnitTest.pm Log Message: removed logic used to diff XML doms and instead use a module XML::SemanticCompare to do the diff moby-live/Perl/MOBY-Server/lib/MOBY/Client MobyUnitTest.pm,1.3,1.4 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm 2008/11/25 17:29:54 1.3 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/lib/MOBY/Client/MobyUnitTest.pm 2008/12/02 18:53:46 1.4 @@ -10,6 +10,7 @@ use strict; use Carp; +use XML::SemanticCompare; use vars qw /$VERSION/; $VERSION = sprintf "%d.%02d", q$Revision$ =~ /: (\d+)\.(\d+)/; @@ -19,7 +20,6 @@ #----------------------------------------------------------------- # load all modules needed #----------------------------------------------------------------- -use XML::Simple; use XML::LibXML; use Data::Dumper; @@ -150,139 +150,9 @@ sub _test_xml { my ( $self, $xml ) = @_; return undef if $self->expected_output =~ m//g; - - # create object - my $xml_simple = new XML::Simple( - ForceArray => 1, - ForceContent => 1, - - #KeepRoot => 1, - SuppressEmpty => 1, - keyattr => [] - ); - - # read both XML files into a HASH - my $control = undef; - my $test = undef; - - # check for invalid XML - eval { $control = $xml_simple->XMLin( $self->expected_output ); }; - return undef if $@; - # check for invalid XML - eval { $test = $xml_simple->XMLin($xml); }; - return undef if $@; - return $self->_compare_current_level( $control, $test, (), () ); -} - -#----------------------------------------------------------------- -# _compare_current_level: -# compares current level of data structures that represent XML -# documents. -# If the current level and all child levels match, a true value -# is returned. Otherwise, undef is returned. -#----------------------------------------------------------------- -sub _compare_current_level { - - # $control is current level in hash - # x_ns are the prefixes that we use - my ( $self, $control, $test, $control_ns, $test_ns ) = @_; - - # if either hash is missing they arent equal - return undef unless $control; - return undef unless $test; - - # get the namespace prefix and uris at the current level - # for each doc and remove from current level of hash - for my $key ( keys %$control ) { - next unless $key =~ m/^xmlns[:]?/; - $control_ns->{''} = ${$control}->{$key} if $key eq 'xmlns'; - $control_ns->{$1} = ${$control}->{$key} if $key =~ m/xmlns\:(.*)$/g; - delete $$control->{$key}; - } - for my $key ( keys %$test ) { - next unless $key =~ m/^xmlns[:]?/; - $test_ns->{''} = ${$test}->{$key} if $key eq 'xmlns'; - $test_ns->{$1} = ${$test}->{$key} if $key =~ m/xmlns\:(.*)$/g; - delete ${$test}->{$key}; - } - - # compare current level number of keys - return undef unless (keys %$control) == (keys %$test); - - # number of keys are equal, so start comparing! - my $matching_nodes = 0; - for my $key ( keys %$control ) { - my $success = 1; - for my $test_key ( keys %$test ) { - # does the key exist? - # 'content' is a special case ... because its text content for a node - if ( ($key eq $test_key and $key eq 'content' ) - or ($self->_get_prefixed_key( $test_key, $test_ns ) eq - $self->_get_prefixed_key( $key, $control_ns ) - and $self->_get_prefixed_key( $key, $control_ns ))) - { - - # are we dealing with scalar values now or more nesting? - if ( ref( ${$control}->{$key} ) eq 'ARRAY' ) { - # both items should be an array - next unless ref(${$test}->{$test_key}) eq 'ARRAY'; - # array sizes should match here ... - next unless @{${$control}->{$key}} == @{${$test}->{$test_key}}; - # more nesting try matching child nodes - my $child_matches = 0; - foreach my $child ( @{ ${$control}->{$key} } ) { - my $matched = undef; - foreach my $test_child ( @{ ${$test}->{$test_key} } ) { - $matched = $self->_compare_current_level( $child, $test_child, $control_ns, $test_ns ); - $child_matches++ if $matched; - last if $matched; - } # end inner foreach - $matching_nodes++ if @{ ${$control}->{$key} } == $child_matches; - } - } else { - # compare scalar values now - # we dont care about whitespace, so we need to trim the text - my $c_text = $self->_clear_whitespace(${$control}->{$key}); - my $t_text = $self->_clear_whitespace(${$test}->{$test_key}); - $matching_nodes++ if $c_text eq $t_text; - last if $c_text eq $t_text; - } - } - } #end inner for - } - - # no differences found! - return undef unless $matching_nodes == (keys %$control); - return 1; -} - -#----------------------------------------------------------------- -# _clear_whitespace: a whitespace trim function -#----------------------------------------------------------------- -sub _clear_whitespace { - my ($self, $text) = @_; - $text =~ s/^\s+//; - $text =~ s/\s+$//; - return $text; -} - -#----------------------------------------------------------------- -# _get_prefixed_key: -# goes through and tries to determine what the namespace URI -# is for a prefix. -# Once a URI is found, the prefix is swapped with URI and -# returned. -#----------------------------------------------------------------- -sub _get_prefixed_key { - my ( $self, $key, $ns_hash ) = @_; - my $prefixed_key = $key; - my $prefix = $1 if $key =~ m/^([\w]+)\:.*/; - $prefixed_key =~ s/$prefix/$ns_hash->{$prefix}/ if $prefix; - - # check for default xmlns - $prefixed_key = $ns_hash->{$prefix} . ":" . $key - if not $prefix and defined $ns_hash->{$prefix}; - return $prefixed_key; + # compare the docs + my $sc = XML::SemanticCompare->new(); + return $sc->compare($self->expected_output, $xml); } #----------------------------------------------------------------- @@ -295,21 +165,8 @@ # empty xml, nothing to test return undef if $xml =~ m//g; #instantiate a parser - my $parser = XML::LibXML->new(); - my $tree = undef; - # try parsing a string or a file - eval {$tree = $parser->parse_string($xml);}; - eval {$tree = $parser->parse_file($xml);} if $@; - return undef if $@; - my $root = $tree->getDocumentElement; - # evaluate the xpath statement - my $results = undef; - eval {$results = $root->find($self->xpath); }; - return undef if $@; - # no results? - return undef unless $results; - # got some hits! - return 1; + my $sc = XML::SemanticCompare->new(); + return $sc->test_xpath($self->xpath, $xml); } #----------------------------------------------------------------- From kawas at dev.open-bio.org Tue Dec 2 18:54:50 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 13:54:50 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021854.mB2IsoJ1006760@dev.open-bio.org> kawas Tue Dec 2 13:54:50 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6725/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: update wsrf-lite version that we use (significant bug fixes in newest version of WSRF::Lite) moby-live/Perl/MOBY-Server Makefile.PL,1.11,1.12 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:53:11 1.11 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:54:50 1.12 @@ -32,7 +32,7 @@ requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires - requires 'WSRF::Lite' => '0.8.2.3'; + requires 'WSRF::Lite' => '0.8.2.6'; if ( not( $^O =~ /MSWin32|Windows_NT/i ) ) { From kawas at dev.open-bio.org Tue Dec 2 19:15:02 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:15:02 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021915.mB2JF2jT006885@dev.open-bio.org> kawas Tue Dec 2 14:15:02 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6850/Perl/MOBY-Server Modified Files: Makefile.PL Log Message: fix wsrf version moby-live/Perl/MOBY-Server Makefile.PL,1.12,1.13 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 18:54:50 1.12 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/Makefile.PL 2008/12/02 19:15:02 1.13 @@ -32,7 +32,7 @@ requires 'XML::SemanticCompare'=> '0'; # MOBY::Async requires - requires 'WSRF::Lite' => '0.8.2.6'; + requires 'WSRF::Lite' => '0.8.2.5'; if ( not( $^O =~ /MSWin32|Windows_NT/i ) ) { From kawas at dev.open-bio.org Tue Dec 2 19:15:31 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:15:31 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021915.mB2JFVAS006925@dev.open-bio.org> kawas Tue Dec 2 14:15:31 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv6890/Perl/MOBY-Server Modified Files: META.yml Log Message: updated 'requires' moby-live/Perl/MOBY-Server META.yml,1.4,1.5 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml 2008/06/05 14:13:52 1.4 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/META.yml 2008/12/02 19:15:31 1.5 @@ -41,4 +41,7 @@ XML::DOM: 0 XML::LibXML: 1.62 XML::XPath: 1.12 -version: 1.05 + XML::SemanticCompare: 0 + XML::Simple: 2.18 + WSRF::Lite: 0.8.2.5 +version: 1.06 From kawas at dev.open-bio.org Tue Dec 2 19:16:19 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:16:19 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021916.mB2JGJoK006965@dev.open-bio.org> kawas Tue Dec 2 14:16:19 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv6930/Perl/MOBY-Client Modified Files: META.yml Log Message: updated 'requires' moby-live/Perl/MOBY-Client META.yml,1.2,1.3 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml 2008/03/05 18:38:40 1.2 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/META.yml 2008/12/02 19:16:19 1.3 @@ -23,6 +23,8 @@ SOAP::Lite: 0.60 URI::Escape: 0 XML::LibXML: 0 - WSRF::Lite: 0 + WSRF::Lite: 0.8.2.5 RDF::Core: 0.51 -version: 1.01 + XML::Simple: 2.18 + XML::SemanticCompare: 0.91 +version: 1.03 From kawas at dev.open-bio.org Tue Dec 2 19:16:52 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:16:52 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021916.mB2JGqhL007005@dev.open-bio.org> kawas Tue Dec 2 14:16:52 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv6970/Perl/MOBY-Client Modified Files: Makefile.PL Log Message: updated 'requires' moby-live/Perl/MOBY-Client Makefile.PL,1.9,1.10 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/11/17 15:30:55 1.9 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:16:52 1.10 @@ -21,6 +21,7 @@ requires 'RDF::Core' => '0.51'; # MOBY::Client::MobyUnitTest depends requires 'XML::Simple' => '2.18'; +requires 'XML::SemanticCompare' => '0.91'; # MOBY::CommonSubs depends requires 'HTML::Entities' => 0; From kawas at dev.open-bio.org Tue Dec 2 19:18:31 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Tue, 2 Dec 2008 14:18:31 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812021918.mB2JIVUe007087@dev.open-bio.org> kawas Tue Dec 2 14:18:31 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Client In directory dev.open-bio.org:/tmp/cvs-serv7052/Perl/MOBY-Client Modified Files: Makefile.PL Log Message: updated wsrf version moby-live/Perl/MOBY-Client Makefile.PL,1.10,1.11 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:16:52 1.10 +++ /home/repository/moby/moby-live/Perl/MOBY-Client/Makefile.PL 2008/12/02 19:18:31 1.11 @@ -27,7 +27,7 @@ requires 'HTML::Entities' => 0; # MOBY::Async requires -requires 'WSRF::Lite' => '0.8.2.2.3'; +requires 'WSRF::Lite' => '0.8.2.5'; auto_install; From senger at dev.open-bio.org Wed Dec 3 12:22:21 2008 From: senger at dev.open-bio.org (Martin Senger) Date: Wed, 3 Dec 2008 07:22:21 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031222.mB3CMLKI012050@dev.open-bio.org> senger Wed Dec 3 07:22:21 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv12031/S/client Modified Files: CentralImpl.java Log Message: revert to 1.57 moby-live/Java/src/main/org/biomoby/client CentralImpl.java,1.59,1.60 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:09:40 1.59 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:22:21 1.60 @@ -1,2139 +1,2139 @@ -// CentralImpl.java -// A default client to the Moby Central service. -// -// senger at ebi.ac.uk -// February 2003 -// - -package org.biomoby.client; - -import org.biomoby.registry.meta.Registry; -import org.biomoby.shared.Central; -import org.biomoby.shared.MobyData; -import org.biomoby.shared.MobyDataType; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyNamespace; -import org.biomoby.shared.MobyPrimaryDataSet; -import org.biomoby.shared.MobyPrimaryDataSimple; -import org.biomoby.shared.MobyRelationship; -import org.biomoby.shared.MobySecondaryData; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.MobyServiceType; -import org.biomoby.shared.NoSuccessException; -import org.biomoby.shared.PendingCurationException; -import org.biomoby.shared.MobyResourceRef; -import org.biomoby.shared.Utils; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.namespace.QName; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.apache.axis.AxisFault; -import org.apache.axis.client.Call; -import org.apache.axis.client.Service; -import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.methods.HeadMethod; -import org.apache.commons.httpclient.params.HttpMethodParams; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.io.PrintStream; -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Vector; -import java.util.TreeMap; -import java.util.Comparator; -import java.util.zip.GZIPInputStream; -import java.util.logging.*; - -/** - * A default implementation of the - * interface {@link org.biomoby.shared.Central Central} - * allowing access to a Moby registry. - *

      - * This class is supposed to be used by all other clients that wish - * to communicate with the Moby Registry, but do not want to know - * about all XML details that are necessary for talking with the Moby Central - * directly. This is an example of a client program: - *

      - * import org.biomoby.shared.Central;
      - * import org.biomoby.shared.MobyException;
      - * import org.biomoby.client.CentralImpl;
      - * import java.util.Map;
      - * import java.util.Iterator;
      - *
      - * public class Test {
      - *
      - *    public static void main (String[] args)
      - *       throws MobyException {
      - *
      - *       Central worker = new CentralImpl();
      - *       Map authorities = worker.getServiceNamesByAuthority();
      - *
      - *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
      - *          Map.Entry entry = (Map.Entry)it.next();
      - *          System.out.println (entry.getKey());
      - *          String[] names = (String[])entry.getValue();
      - *          for (int i = 0; i < names.length; i++)
      - *             System.out.println ("\t" + names[i]);
      - *       }
      - *    }
      - * }
      - *
      - * - * @author Martin Senger - * @version $Id$ - */ - -public class CentralImpl - implements Central, SimpleCache { - - private URL endpoint; - private String uri; - protected boolean debug = false; - - /** Common central used to if getDefaultCentral() is called */ - protected static Map defaultCentrals = new HashMap(); - - /** Default location (endpoint) of a Moby registry. */ - public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; - - /** Default namespace used by the contacted Moby registry. */ - public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; - - /** - * The META-INF resource file that will be checked to determine what - * default class should be instantiated in order to create a Central Implementation - * when getDefaultCentral() is called. - */ - public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; - /** The class to use for getDefaultCentral if all else fails */ - public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; - private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); - - /** - * Thread local that gives each thread its own - * DocumentBuilderFactory (since it is not thread-safe). Code taken - * from Apache's JaxpUtils. - */ - public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { - protected synchronized Object initialValue() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware (true); - return dbf; - } - }; - - - /************************************************************************* - * Default constructor. It connects to a default Moby registry - * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace - * (as defined int {@link #DEFAULT_NAMESPACE}). - *************************************************************************/ - public CentralImpl() - throws MobyException { - this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); - } - - /************************************************************************* - * Constructor allowing to specify which Moby Registry to use. - * - * @throws MobyException if 'endpoint' is not a valid URL, or if no - * DOM parser is available - *************************************************************************/ - public CentralImpl (String endpoint) - throws MobyException { - this (endpoint, DEFAULT_NAMESPACE); - } - - /************************************************************************* - * Constructor allowing to specify which Moby Registry and what - * namespace to use. If any of the parameters is null, its default - * value is used instead. - *

      - * @throws MobyException if 'endpoint' is not a valid URL, or if no - * DOM parser was found - *************************************************************************/ - public CentralImpl (String endpoint, String namespace) - throws MobyException { - - if (endpoint == null || "".equals (endpoint.trim())) - endpoint = DEFAULT_ENDPOINT; - if (namespace == null || "".equals (namespace.trim())) - namespace = DEFAULT_NAMESPACE; - - try { - this.endpoint = new URL (endpoint); - } catch (MalformedURLException e) { - throw new MobyException ("Bad URL: " + endpoint); - } - this.uri = namespace; - - cache = new Hashtable(); - useCache = true; - } - - /************************************************************************* - * Loads a DOM Document from an InputStream. Uses thread-safe - * mechanism. - *************************************************************************/ - public static Document loadDocument (InputStream input) - throws MobyException { - try { - DocumentBuilderFactory dbf - = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); - DocumentBuilder db = dbf.newDocumentBuilder(); - return (db.parse (input)); - } catch (Exception e) { - throw new MobyException ("Problem with reading XML input: " + e.toString(), e); - } - } - - /************************************************************************* - * Call 'method' with 'parameters' and return its result. - *************************************************************************/ - protected Object doCall (String method, Object[] parameters) - throws MobyException { - - Call call = null; - try { - Service service = new Service(); - call = (Call) service.createCall(); - call.setTargetEndpointAddress (endpoint); - call.setTimeout (new Integer (0)); - - call.setSOAPActionURI (uri + "#" + method); - - if (debug) { - System.err.println ("METHOD CALL: " + method); - System.err.println ("------------"); - if (parameters.length > 0) - System.err.println (parameters[0] + "\n"); - System.err.println ("------------\n"); - - Object result = call.invoke (uri, method, parameters); - - System.err.println ("METHOD RETURN:"); - System.err.println ("------------"); - if (result != null) - System.err.println (result + "\n"); - System.err.println ("------------\n"); - - return resultToString (result); - - } else { - return resultToString (call.invoke (uri, method, parameters)); - } - - } catch (AxisFault e) { - throw new MobyException - (formatFault (e, - endpoint.toString(), - (call == null ? null : call.getOperationName())), - e); -// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); - - } catch (Exception e) { - throw new MobyException (e.toString(), e); -// e.printStackTrace(); - } - } - - - /************************************************************************** - * Parse the given XML sniplet to find tag 'success'. If it has value '1' - * look further for tag 'id' and return it back (or return an empty string - * if ID is not there). Otherwise raise an exception with the 'culprit' - * and with the message from the tag 'message'.

      - * - * The return value is a two-element long array. The first element - * is the ID (given by BioMobe registry), and the second element - * is RDF corresponding with the registered object (BioMoby - * returns this only for service instances, so for other objects - * this will be null).

      - * - * This is how the XML is supposed to look: - * - * - * - * - * - * - * - * Success takes the value "1" to indicate success, "0" to - * indicate failure, and "-1" to indicate "Pending Curation". - *************************************************************************/ - protected String[] checkRegistration (String xml, Object culprit) - throws MobyException, NoSuccessException, PendingCurationException { - - String id = "", success = "0", message = "", rdf = ""; - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); - Element root = document.getDocumentElement(); - - NodeList children = root.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - if (children.item (i).getNodeType() != Node.ELEMENT_NODE) - continue; - Element elem = (Element)children.item (i); - if (elem.getNodeName().equals ("id")) { - if (elem.getFirstChild() != null) - id = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals("success")) { - if (elem.getFirstChild() != null) - success = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals ("message")) { - if (elem.getFirstChild() != null) - message = elem.getFirstChild().getNodeValue(); - } else if (elem.getNodeName().equals ("RDF")) { - if (elem.getFirstChild() != null) - rdf = elem.getFirstChild().getNodeValue(); - } - } - - if (success.equals ("0")) - throw new NoSuccessException (message, culprit); - else if (success.equals ("-1")) - throw new PendingCurationException(); - return new String[] { id, rdf }; - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing input - * data types and their usage in the given service. Only data considered - * primary are included. Note that the main job of converting to XML is - * done by instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - * - *************************************************************************/ - protected String buildPrimaryInputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryInputs = service.getPrimaryInputs(); - buf.append ("\n"); - for (int i = 0; i < primaryInputs.length; i++) - buf.append (primaryInputs[i].toXML()); - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing input - * data types and their usage in the given service. Only data considered - * secondary are included. Note that the main job of converting to XML is - * done by instances of MobySecondaryData. - * - * The returned XML looks like this: - * - * - * - *************************************************************************/ - protected String buildSecondaryInputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] secInputs = service.getSecondaryInputs(); - buf.append ("\n"); - for (int i = 0; i < secInputs.length; i++) { - buf.append (secInputs[i].toXML()); - } - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML created from the definitions representing output - * data types and their usage in the given service. Only data considered - * primary are included. Note that the main job of converting to XML is - * done by instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - * - * - *************************************************************************/ - protected String buildOutputTag (MobyService service) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryOutputs = service.getPrimaryOutputs(); - buf.append ("\n"); - for (int i = 0; i < primaryOutputs.length; i++) - buf.append (primaryOutputs[i].toXML()); - buf.append ("\n"); - return new String (buf); - } - - /************************************************************************** - * Return a piece of XML represented a query object (an object used - * to find a service). - * - * The returned XML looks like this: - * - * - * - * - * - * - * - * - * - * - * - * ServiceTypeTerm - * ServiceName - * moby - * http://desired.service.provider; - * 1|0 - * 1|0 - * 1|0 - * - * something - * .... - * .... - * - *************************************************************************/ - protected String buildQueryObject (MobyService service, - String[] keywords, - boolean expandObjects, - boolean expandServices, - boolean authoritative) { - if (service == null) { - service = new MobyService ("dummy"); - service.setCategory (""); - } - StringBuffer buf = new StringBuffer(); - - buf.append ("\n\n"); - MobyData[] pi = service.getPrimaryInputs(); - if (pi.length > 0) { - for (int i = 0; i < pi.length; i++) - buf.append (pi[i].toXML()); - } - buf.append ("\n\n"); - - buf.append ("\n\n"); - MobyData[] po = service.getPrimaryOutputs(); - if (po.length > 0) { - for (int i = 0; i < po.length; i++) - buf.append (po[i].toXML()); - } - buf.append ("\n\n"); - - buf.append ("" + service.getType() + "\n"); - - String name = service.getName(); - if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) - buf.append ("" + service.getName() + "\n"); - - String sigURL = service.getSignatureURL(); - if (!sigURL.equals ("")) - buf.append ("" + sigURL + "\n"); - - buf.append ("" + service.getCategory() + "\n"); - buf.append ("" + service.getAuthority() + "\n"); - - buf.append (""); - buf.append (expandObjects ? "1" : "0"); - buf.append ("\n"); - - buf.append (""); - buf.append (expandServices ? "1" : "0"); - buf.append ("\n"); - - buf.append (""); - buf.append (authoritative ? "1" : "0"); - buf.append ("\n"); - - buf.append ("\n"); - if (keywords != null && keywords.length > 0) { - for (int i = 0; i < keywords.length; i++) { - buf.append (""); - buf.append (keywords[i]); - buf.append ("\n"); - } - } - buf.append ("\n"); - - return new String (buf); - } - - /************************************************************************** - * Extract one or more MobyService objects from the given XML piece. - * The XML should look like this: - *

      -     *  <Services>
      -     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
      -     *      <serviceType>Service_Ontology_Term</serviceType>
      -     *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
      -     *      <contactEmail>your at email.addy.here</contactEmail>
      -     *      <signatureURL>http://service.RDF.here</signatureURL>
      -     *      <URL>http://service.endpoint.here/scriptname</URL>
      -     *      <authoritative>1</authoritative>
      -     *      <Input>
      -     *           <!-- one or more Simple and/or Complex Primary articles -->
      -     *      </Input>
      -     *      <Output>
      -     *           <!-- one or more Simple and/or Complex Primary articles --> 
      -     *      </Output>
      -     *      <secondaryArticles>
      -     *           <!-- one or more Secondary articles -->
      -     *      </secondaryArticles>
      -     *      <Description><![CDATA[free text description here]]></Description>
      -     *    </Service>
      -     *    ...  <!--  one or more Service blocks may be returned -->
      -     *    ...
      -     *    ...
      -     *  </Services>
      -     * 
      - * @throws MobyException if the XML document is invalid - *************************************************************************/ - public MobyService[] extractServices (String xml) - throws MobyException { - - Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); - NodeList list = document.getElementsByTagName ("Service"); - MobyService[] results = new MobyService [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyService service = new MobyService (elem.getAttribute ("serviceName")); - service.setAuthority (elem.getAttribute ("authURI")); - service.setLSID (elem.getAttribute ("lsid")); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("Description")) { - service.setDescription (getFirstValue (children.item (j))); - } else if (nodeName.equals ("Category")) { - service.setCategory (getFirstValue (children.item (j))); - } else if (nodeName.equals ("URL")) { - service.setURL (getFirstValue (children.item (j))); - } else if (nodeName.equals ("signatureURL")) { - service.setSignatureURL (getFirstValue (children.item (j))); - } else if (nodeName.equals ("contactEmail")) { - service.setEmailContact (getFirstValue (children.item (j))); - } else if (nodeName.equals ("serviceType")) { - service.setType (getFirstValue (children.item (j))); - MobyServiceType mst = new MobyServiceType(service.getType()); - NamedNodeMap map = (children.item (j).getAttributes()); - if (map != null) { - Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); - if (node != null) - mst.setLSID(node.getNodeValue()); - } - service.setServiceType(mst); - } else if (nodeName.equals ("authoritative")) { - String authoritative = getFirstValue (children.item (j)); - service.setAuthoritative (authoritative.equals ("1") ? true : false); - } else if (nodeName.equals ("Input")) { - // - // - // - // ... - // - // - // ...... - // ...... - // - // - NodeList inputs = children.item (j).getChildNodes(); - for (int k = 0; k < inputs.getLength(); k++) { - if (inputs.item (k).getNodeName().equals ("Simple")) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); - service.addInput (data); - } else if (inputs.item (k).getNodeName().equals ("Collection")) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); - service.addInput (data); - } - } - } else if (nodeName.equals ("Output")) { - // - // - // - NodeList inputs = children.item (j).getChildNodes(); - for (int k = 0; k < inputs.getLength(); k++) { - if (inputs.item (k).getNodeName().equals ("Simple")) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); - service.addOutput (data); - } else if (inputs.item (k).getNodeName().equals ("Collection")) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); - service.addOutput (data); - } - } - - } else if (nodeName.equals ("secondaryArticles")) { - // - // ... - // - NodeList parameters = children.item (j).getChildNodes(); - for (int k = 0; k < parameters.getLength(); k++) { - if (parameters.item (k).getNodeName().equals ("Parameter")) { - MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); - service.addInput (data); - } - } - } - } - results [i] = service; - } - return results; - } - - // protect against null values - protected String getFirstValue (Node child) { - Node node = child.getFirstChild(); - if (node == null) return ""; - String value = node.getNodeValue(); - if (value == null) return ""; - return value; - } - - protected String getFirstValue (NodeList children) { - if (children.item(0) != null && children.item(0).hasChildNodes()) { - children.item(0).normalize(); - return getFirstValue (children.item(0)); - } - return ""; - } - - /************************************************************************** - * - * Implementing SimpleCache interface. - * - * Why to have an interface for such trivial thing? Well, because - * I needed to overwrite the caching mechanism in the subclasses - * so I needed to have all caching functions as separate methods - - * that's why I have collect them in an interface. - * - *************************************************************************/ - private Hashtable cache; // this is the cache itself - private boolean useCache; // this signal that we are actually caching things - - // not used here - public String createId (String rootName, - String semanticType, String syntaxType, - long lastModified, - Properties props) { - return ""; // not used here - } - - // check existence of a cached object - public boolean existsInCache (String id) { - synchronized (cache) { - if (useCache) return cache.containsKey (id); - else return false; - } - } - - // retrieve from cache - public Object getContents (String id) { - synchronized (cache) { - if (useCache) return cache.get (id); - else return null; - } - } - - // cache an object - public void setContents (String id, java.lang.Object data) { - synchronized (cache) { - if (useCache) cache.put (id, data); - } - } - - // in this implementation, it clears the whole cache, regardless - // what 'id' is passed - public void removeFromCache (String id) { - cache.clear(); - } - - /************************************************************************** - * - * And the other methods related to caching (but not part of the - * SimpleCache interface). - * - **************************************************************************/ - - /************************************************************************** - * By default, caching is enabled to reduce network traffic. - * Setting this to false will clear the cache, and not cache any - * further calls unless it is set to true again.

      - * - * @param shouldCache whether retrieveXXX call results should be - * cached in case they are called again (i.e. don't request - * MobyCentral every time) - **************************************************************************/ - public void setCacheMode (boolean shouldCache) { - useCache = shouldCache; - if (! useCache) - removeFromCache (null); - } - - /************************************************************************** - * Find if caching is currently enabled. - * - * @return true if caching is enabled - **************************************************************************/ - public boolean getCacheMode(){ - return useCache; - } - - /************************************************************************** - * Parses and imports the following XML. - *

      -     * <serviceNames>
      -     *   <serviceName name="serviceName" authURI='authority.info.here'/>
      -     *   ...
      -     *   ...
      -     * </serviceNames>
      -     * 
      - * - * @deprecated Replaced by {@link - * #getServiceNamesByAuthority}. The reason is that this method - * returns a random result if there are more services with the - * same name but belonging to different authorities.

      - * - *************************************************************************/ - public Map getServiceNames() - throws MobyException { - - String result = (String)doCall ("retrieveServiceNames", - new Object[] {}); - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceName"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - results.put (elem.getAttribute ("name"), - elem.getAttribute ("authURI")); - } - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *

      -     * <serviceNames>
      -     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
      -     *   ...
      -     *   ...
      -     * </serviceNames>
      -     * 
      - * - * @return a Map which has authorities as keys, and String arrays - * with service names as a values. - *************************************************************************/ - public Map getServiceNamesByAuthority() - throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML (result, true); - } - - /************************************************************************** - * Similar to {@link #getServiceNamesByAuthority} but the - * resulting Map contains slightly more.

      - * - * @return a Map which has authorities as keys, and arrays of - * MobyServices as a values. Each MobyService is filled with its - * name, authority and LSID. - *************************************************************************/ - public Map getServicesByAuthority() - throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML (result, false); - } - - // - protected String getServiceNamesByAuthorityAsXML() - throws MobyException { - return (String)doCall ("retrieveServiceNames", - new Object[] {}); - } - - // if onlyNames == true - // Map: authority name -> String[] - // (filled with service namea) - // else - // Map: authority name -> MobyService[] - // (filled with service name, authority and lsid) - protected Map createServicesByAuthorityFromXML (String result, - boolean onlyNames) - throws MobyException { - - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceName"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String name = elem.getAttribute ("name"); - String auth = elem.getAttribute ("authURI"); - Vector v = - (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); - if (onlyNames) { - v.addElement (name); - } else { - MobyService ms = new MobyService (name); - ms.setAuthority (auth); - ms.setLSID (elem.getAttribute ("lsid")); - v.addElement (ms); - } - results.put (auth, v); - } - - // change values of type Vector to MobyService[] or String[] - for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry)it.next(); - Vector v = (Vector)entry.getValue(); - if (onlyNames) { - String[] sNames = new String [v.size()]; - v.copyInto (sNames); - entry.setValue (sNames); - } else { - MobyService[] mss = new MobyService [v.size()]; - v.copyInto (mss); - entry.setValue (mss); - } - } - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     *  <serviceProviders>
      -     *     <serviceProvider name="authority.URI.here"/>
      -     *          ...
      -     *          ...
      -     *  </serviceProviders>
      -     * 
      - *************************************************************************/ - public String[] getProviders() - throws MobyException { - - String cacheId = "retrieveServiceProviders"; - String[] cachedResults = (String[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = (String)doCall ("retrieveServiceProviders", - new Object[] {}); - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceProvider"); - String[] results = new String [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) - results[i] = ((Element)list.item (i)).getAttribute ("name"); - - // Add this data to the cache in case we get called again - setContents (cacheId, results); - - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     *  <serviceTypes>
      -     *     <serviceType name="serviceName" lsid="...">
      -     *            <Description><![CDATA[free text description here]]></Description>
      -     *            <contactEmail>...</contactEmail>
      -     *            <authURI>...</authURI>
      -     *     </serviceType>
      -     *          ...
      -     *          ...
      -     *  </serviceTypes>
      -     * 
      - *************************************************************************/ - public Map getServiceTypes() - throws MobyException { - String result = getServiceTypesAsXML(); - Map results = new TreeMap (getStringComparator()); - MobyServiceType[] types = createServiceTypesFromXML (result); - for (int i = 0; i < types.length; i++) { - results.put (types[i].getName(), - types[i].getDescription()); - } - return results; - } - - // - protected String getServiceTypesAsXML() - throws MobyException { - return (String)doCall ("retrieveServiceTypes", - new Object[] {}); - } - - // but be aware that the created MobyServiceTypes are not complete - // - they do not have the relationship information; that's why - // this method is not public; the full service types are available - // from CentralDigest implementations - protected MobyServiceType[] createServiceTypesFromXML (String result) - throws MobyException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("serviceType"); - if (list == null || list.getLength() == 0) - return new MobyServiceType[] {}; - MobyServiceType[] results = new MobyServiceType [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); - st.setLSID (elem.getAttribute ("lsid")); - st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); - st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); - st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); - results[i] = st; - } - java.util.Arrays.sort (results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     *  <Namespaces>
      -     *     <Namespace name="namespace" lsid="...">
      -     *            <Description><![CDATA[free text description here]]></Description>
      -     *            <contactEmail>...</contactEmail>
      -     *            <authURI>...</authURI>
      -     *     </Namespace>
      -     *          ...
      -     *          ...
      -     *  </Namespaces>
      -     * 
      - *************************************************************************/ - public MobyNamespace[] getFullNamespaces() - throws MobyException { - - String result = getNamespacesAsXML(); - return createNamespacesFromXML (result); - } - - // - protected String getNamespacesAsXML() - throws MobyException { - return (String)doCall ("retrieveNamespaces", - new Object[] {}); - } - - // - protected MobyNamespace[] createNamespacesFromXML (String result) - throws MobyException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); - if (list == null || list.getLength() == 0) { - return new MobyNamespace[] {}; - } - MobyNamespace[] results = new MobyNamespace [list.getLength()]; - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); - nm.setLSID (elem.getAttribute ("lsid")); - nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); - nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); - nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); - results[i] = nm; - } - - java.util.Arrays.sort (results); - return results; - } - - /************************************************************************** - * - * @deprecated Replaced by {@link #getFullNamespaces} that gives - * more information for the same price.

      - *************************************************************************/ - public Map getNamespaces() - throws MobyException { - - Map results = new TreeMap (getStringComparator()); - MobyNamespace[] namespaces = getFullNamespaces(); - for (int i = 0; i < namespaces.length; i++) { - results.put (namespaces[i].getName(), - namespaces[i].getDescription()); - } - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *

      -     *  <objectNames>
      -     *     <Object name="objectName" lsid="...">
      -     *            <Description><![CDATA[free text description here]]></Description>
      -     *     </Object>
      -     *          ...
      -     *          ...
      -     *  </objectNames>
      -     * 
      - *************************************************************************/ - public Map getDataTypeNames() - throws MobyException { - String result = getDataTypeNamesAsXML(); - return createDataTypeNamesFromXML (result, true); - } - - // - protected String getDataTypeNamesAsXML() - throws MobyException { - return (String)doCall ("retrieveObjectNames", - new Object[] {}); - } - - // if onlyNames == true - // Map: data type name -> description (String) - // else - // Map: data type name -> MobyDataType[] - // (filled with name, description, and lsid) - protected Map createDataTypeNamesFromXML (String result, - boolean onlyNames) - throws MobyException { - - // parse returned XML - Map results = new TreeMap (getStringComparator()); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Object"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String name = elem.getAttribute ("name"); - if (name == null) - continue; // ignore no-named data types - String desc = ""; - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("Description")) { - desc = getFirstValue (children.item (j)); - break; - } - } - if (onlyNames) { - results.put (name, desc); - } else { - MobyDataType dt = new MobyDataType (name); - dt.setDescription (desc); - dt.setLSID (elem.getAttribute ("lsid")); - results.put (name, dt); - } - } - return results; - } - - - /************************************************************************** - * Parses and imports the following XML. An example: - * - *
      -     * <retrieveObjectDefinition>
      -     *   <objectType lsid="...">go_term</objectType>
      -     *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
      -     *   <authURI>http://www.illuminae.com</authURI>
      -     *   <contactEmail>markw at illuminae.com</contactEmail>
      -     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      -     *      <objectType articleName=''>urn:lsid:biomoby.org:objectclass:object</objectType>
      -     *   </Relationship>
      -     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
      -     *      <objectType articleName='Term'>urn:lsid:biomoby.org:objectclass:string</objectType>
      -     *      <objectType articleName='Definition'>urn:lsid:biomoby.org:objectclass:string</objectType>
      -     *   </Relationship>
      -     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:has'>
      -     *      <objectType articleName='Problems'>urn:lsid:biomoby.org:objectclass:string</objectType>
      -     *      <objectType articleName='Issues'>urn:lsid:biomoby.org:objectclass:string</objectType>
      -     *   </Relationship>
      -     * </retrieveObjectDefinition>
      -     * 
      - *************************************************************************/ - public MobyDataType getDataType (String dataTypeName) - throws MobyException, NoSuccessException { - - String result = getDataTypeAsXML (dataTypeName); - return createDataTypeFromXML (result, dataTypeName); - } - - public MobyDataType[] getDataTypes() - throws MobyException, NoSuccessException { - Map datatypeMap = getDataTypeNames(); - MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; - int i = 0; - for(String dataTypeName: datatypeMap.keySet()){ - datatypes[i++] = getDataType(dataTypeName); - } - return datatypes; - } - - protected String getDataTypeAsXML (String dataTypeName) - throws MobyException, NoSuccessException { - - return (String)doCall ("retrieveObjectDefinition", - new Object[] { - "" + - "" + dataTypeName + "" + - "" - }); - } - - protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) - throws MobyException, NoSuccessException { - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); - NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); - if (list == null || list.getLength() == 0) - throw new NoSuccessException ("Data Type name was not found.", - dataTypeName); - MobyDataType data = null; - Element elem = (Element)list.item (0); - NodeList children = elem.getChildNodes(); - - // first find the "real" (LSID-ized) data type name - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("objectType")) { - data = new MobyDataType (getFirstValue (children.item (j))); - data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); - break; - } - } - - // if not found (unprobable) use the name given by the caller - if (data == null) - data = new MobyDataType (dataTypeName); - - // now fill the data type object with the rest of attributes - for (int j = 0; j < children.getLength(); j++) { - String nodeName = children.item (j).getNodeName(); - if (nodeName.equals ("Description")) { - data.setDescription (getFirstValue (children.item (j))); - } else if (nodeName.equals ("authURI")) { - data.setAuthority (getFirstValue (children.item (j))); - } else if (nodeName.equals ("contactEmail")) { - data.setEmailContact (getFirstValue (children.item (j))); - } else if (nodeName.equals ("Relationship")) { - String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); - if (relationshipType.endsWith ("isa")) { - - NodeList parents = children.item (j).getChildNodes(); - for (int k = 0; k < parents.getLength(); k++) { - if (parents.item (k).getNodeName().equals ("objectType")) { - data.addParentName (getFirstValue (parents.item (k))); - } - } - } else if (relationshipType.endsWith ("hasa")) { - - NodeList belows = children.item (j).getChildNodes(); - for (int k = 0; k < belows.getLength(); k++) { - if (belows.item (k).getNodeName().equals ("objectType")) { - data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), - getFirstValue (belows.item (k)), - Central.iHASA ); - } - } - } else if (relationshipType.endsWith ("has")) { - - NodeList belows = children.item (j).getChildNodes(); - for (int k = 0; k < belows.getLength(); k++) { - if (belows.item (k).getNodeName().equals ("objectType")) { - data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), - belows.item (k).getFirstChild().getNodeValue(), - Central.iHAS ); - } - } - } - } - } - return data; - } - - /************************************************************************** - * - *************************************************************************/ - public String getServiceWSDL (String serviceName) - throws MobyException, NoSuccessException { - - Map names = getServiceNames(); - - for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry)it.next(); - if ( ((String)entry.getKey()).equals (serviceName) ) - return getServiceWSDL (serviceName, (String)entry.getValue()); - } - - throw new NoSuccessException ("Service not found.", serviceName); - } - - /************************************************************************** - * - *************************************************************************/ - public String getServiceWSDL (String serviceName, String authority) - throws MobyException, NoSuccessException { - - String cacheId = "getServiceWSDL" + serviceName + ":" + authority; - String cachedResults = (String)getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("retrieveService", - new Object[] { - "" + - "" + - "" - }); - - // parse returned XML - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - Element service = document.getDocumentElement(); - Node wsdl = service.getFirstChild(); - if (wsdl == null) - throw new NoSuccessException ("Service not found OR WSDL is not available.", - serviceName + " (" + authority + ")"); - - String results = wsdl.getNodeValue(); - setContents (cacheId, results); - return results; - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterDataTypeXML (MobyDataType dataType) { - - // build the ISA tag (expressing hierarchy of data types) - String[] names = dataType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < names.length; i++) { - buf.append (""); - buf.append (names[i]); - buf.append (""); - buf.append ("\n"); - } - - // build the HASA/HAS tags (expressing containments of data types) - MobyRelationship[] children = dataType.getChildren(); - StringBuffer buf2 = new StringBuffer(); // for HASA - StringBuffer buf3 = new StringBuffer(); // for HAS - for (int i = 0; i < children.length; i++) { - if (children[i].getRelationshipType() == Central.iHASA) { - buf2.append (""); - buf2.append (children[i].getDataTypeName()); - buf2.append (""); - } else if (children[i].getRelationshipType() == Central.iHAS) { - buf3.append (""); - buf3.append (children[i].getDataTypeName()); - buf3.append (""); - } - } - - return - "" + - "" + dataType.getName() + "" + - "" + - "" + - "" + new String (buf) + - "" + - "" + new String (buf2) + - "" + - "" + new String (buf3) + - "" + - "" + dataType.getAuthority() + "" + - "" + dataType.getEmailContact() + "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerDataType (MobyDataType dataType) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerObjectClass", - new Object[] { getRegisterDataTypeXML (dataType) }); - dataType.setId (checkRegistration (result, dataType)[0]); - } - - /************************************************************************* - * B - *************************************************************************/ - public void unregisterDataType (MobyDataType dataType) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterObjectClass", - new Object[] { - "" + - "" + dataType.getName() + "" + - "" - }); - checkRegistration (result, dataType); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterServiceTypeXML (MobyServiceType serviceType) { - - // build the ISA tag (expressing hierarchy of service types) - String[] names = serviceType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < names.length; i++) { - buf.append (""); - buf.append (names[i]); - buf.append (""); - buf.append ("\n"); - } - - return - "" + - "" + serviceType.getName() + "" + - "" + serviceType.getEmailContact() + "" + - "" + serviceType.getAuthority() + "" + - "" + - "" + - "" + new String (buf) + - "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerServiceType (MobyServiceType serviceType) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerServiceType", - new Object[] { getRegisterServiceTypeXML (serviceType) }); - serviceType.setId (checkRegistration (result, serviceType)[0]); - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterServiceType (MobyServiceType serviceType) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterServiceType", - new Object[] { - "" + - "" + serviceType.getName() + "" + - "" - }); - checkRegistration (result, serviceType); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterNamespaceXML (MobyNamespace namespace) { - return - "" + - "" + namespace.getName() + "" + - "" + namespace.getEmailContact() + "" + - "" + namespace.getAuthority() + "" + - "" + - "" + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerNamespace (MobyNamespace namespace) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("registerNamespace", - new Object[] { getRegisterNamespaceXML (namespace) }); - namespace.setId (checkRegistration (result, namespace)[0]); - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterNamespace (MobyNamespace namespace) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterNamespace", - new Object[] { - "" + - "" + namespace.getName() + "" + - "" - }); - checkRegistration (result, namespace); - } - - /************************************************************************* - * - *************************************************************************/ - public String getRegisterServiceXML (MobyService service) { - return - "" + - "" + service.getCategory() + "" + - "" + service.getName() + "" + - "" + service.getType() + "" + - "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + - "" + service.getAuthority() + "" + - "" + escapeXML (service.getSignatureURL()) + "" + - "" + escapeXML (service.getURL()) + "" + - "" + service.getEmailContact() + "" + - "" + (service.isAuthoritative() ? "1" : "0") + "" + - "" + - "" + - buildPrimaryInputTag (service) + - buildSecondaryInputTag (service) + - buildOutputTag (service) + - ""; - } - - /************************************************************************* - * - *************************************************************************/ - public void registerService (MobyService service) - throws MobyException, NoSuccessException, PendingCurationException { - - String result = - (String)doCall ("registerService", - new Object[] { getRegisterServiceXML (service) }); - String[] registered = checkRegistration (result, service); - service.setId (registered [0]); - service.setRDF (registered [1]); - String pathToRDF = service.getPathToRDF(); - if ( ! pathToRDF.equals ("") ) { - File fileRDF = new File (pathToRDF); - try { - PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); - fileout.println (registered [1]); - fileout.close(); - } catch (IOException e) { - StringBuffer buf = new StringBuffer (100); - buf.append ("Failed to save RDF in '"); - buf.append (fileRDF.getAbsolutePath() + "'. "); - buf.append (e.toString()); - try { - File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); - PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); - fileout.println (registered [1]); - fileout.close(); - buf.append ("\nReturned RDF file was therefore stored in: "); - buf.append (tmpFile.getAbsolutePath()); - } catch (IOException e2) { - buf.append ("\nEven saving in a temporary file failed: "); - buf.append (e2.toString()); - } - throw new MobyException (buf.toString()); - } - } - } - - /************************************************************************* - * - *************************************************************************/ - public void unregisterService (MobyService service) - throws MobyException, NoSuccessException, PendingCurationException { - String result = - (String)doCall ("deregisterService", - new Object[] { - "" + - "" + service.getAuthority() + "" + - "" + service.getName() + "" + - "" - }); - checkRegistration (result, service); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (String serviceType) - throws MobyException { - if (serviceType == null) - return new MobyService[] {}; - MobyService pattern = new MobyService ("dummy"); - pattern.setCategory (""); - pattern.setType (serviceType); - return findService (pattern, null); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (String[] keywords) - throws MobyException { - if (keywords == null) - return new MobyService[] {}; - return findService (null, keywords); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (MobyService pattern) - throws MobyException { - if (pattern == null) - return new MobyService[] {}; - return findService (pattern, null); - } - - /************************************************************************** - * - *************************************************************************/ - public MobyService[] findService (MobyService pattern, String[] keywords) - throws MobyException { - return findService (pattern, keywords, true, true); - } - - /************************************************************************** - * All 'findService' methods end up here. - *************************************************************************/ - public MobyService[] findService (MobyService pattern, String[] keywords, - boolean includeChildrenServiceTypes, - boolean includeParentDataTypes) - throws MobyException { - if (pattern == null) { - pattern = new MobyService ("dummy"); - pattern.setCategory (""); - } - - String result = - getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); - MobyService[] services = extractServices (result); - return services; - } - - // ...actually all 'findService' methods end up here - protected String getServicesAsXML (MobyService pattern, String[] keywords, - boolean includeChildrenServiceTypes, - boolean includeParentDataTypes) - throws MobyException { - String[] query = new String[] { - "" + - buildQueryObject (pattern, keywords, - includeParentDataTypes, - includeChildrenServiceTypes, - false) + - "" - }; - return (String)doCall ("findService", query); - } - - /************************************************************************** - * - *************************************************************************/ - public String call (String methodName, String inputXML) - throws MobyException { - Object result; - if (inputXML == null || inputXML.equals ("")) - result = doCall (methodName, new Object[] { }); - else - result = doCall (methodName, new Object[] { inputXML }); - return (String)result; - } - - /************************************************************************** - * - *************************************************************************/ - protected static String resultToString (Object result) - throws MobyException { - if (result == null) - throw new MobyException ("Returned result is null."); - if (result instanceof String) - return (String)result; - if (result instanceof String[]) { - String[] tmp = (String[])result; - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < tmp.length; i++) - buf.append (tmp[i]); - return new String (buf); - } - if (result instanceof byte[]) - return new String ((byte[])result); - - throw new MobyException ("Unknown type of result: " + result.getClass().getName()); - } - - /************************************************************************** - * - *************************************************************************/ - public boolean setDebug (boolean enabled) { - boolean oldMode = debug; - debug = enabled; - return oldMode; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     * <Relationships>
      -     *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
      -     *     <serviceType>urn:lsid:biomoby.org:servicetype:analysis</serviceType>
      -     *     <serviceType>urn:lsid:biomoby.org:servicetype:service</serviceType>
      -     *   </Relationship>
      -     * </Relationships>
      -     * 
      - *************************************************************************/ - public String[] getServiceTypeRelationships (String serviceTypeName, - boolean expand) - throws MobyException { - String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); - return createServiceTypeRelationshipsFromXML (result); - } - - // - protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, - boolean expand) - throws MobyException { - return - (String)doCall ("Relationships", - new Object[] { - "" + - "" + serviceTypeName + "" + - "" + Central.ISA + "" + - "" + (expand ? "1" : "0") + "" + - "" - }); - } - - // - protected String[] createServiceTypeRelationshipsFromXML (String result) - throws MobyException { - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("serviceType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - } - String[] results = new String [v.size()]; - v.copyInto (results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     *<Relationships>
      -     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
      -     *  </Relationship>
      -     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
      -     *  </Relationship>
      -     *</Relationships>
      -     * 
      - * - * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an - * attributes 'lsid' and 'articleName' in <objectType> element. - *************************************************************************/ - public Map getDataTypeRelationships (String dataTypeName) - throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName; - Map cachedResults = (Map)getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("Relationships", - new Object[] { - "" + - "" + dataTypeName + "" + - "" + Central.ISA + "" + - "" + Central.HASA + "" + - "" + Central.HAS + "" + - "1" + - "" - }); - - // parse returned XML - Map results = new HashMap(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - String relType = elem.getAttribute ("relationshipType"); - NodeList children = elem.getChildNodes(); - Vector v = new Vector(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("objectType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - String[] names = new String [v.size()]; - v.copyInto (names); - results.put (relType, names); - } - - setContents (cacheId, results); - return results; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     *<Relationships>
      -     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
      -     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
      -     *  </Relationship>
      -     *</Relationships>
      -     * 
      - *************************************************************************/ - public String[] getDataTypeRelationships (String dataTypeName, - String relationshipType) - throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; - String[] cachedResults = (String[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = - (String)doCall ("Relationships", - new Object[] { - "" + - "" + dataTypeName + "" + - "" + relationshipType + "" + - "1" + - "" - }); - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Relationship"); - - // it should always be just one element in this list - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - NodeList children = elem.getChildNodes(); - for (int j = 0; j < children.getLength(); j++) { - if (children.item (j).getNodeName().equals ("objectType")) { - v.addElement (getFirstValue (children.item (j))); - } - } - } - String[] results = new String [v.size()]; - v.copyInto (results); - - setContents (cacheId, results); - return results; - } - -// /************************************************************************** -// * -// *************************************************************************/ -// public MobyRelationship[] getRelationships (String dataTypeName) -// throws MobyException { -// return null; -// } - - - /************************************************************************** - * - *************************************************************************/ - public String getRegistryEndpoint() { - return endpoint.toString(); - } - - /************************************************************************** - * - *************************************************************************/ - public String getRegistryNamespace() { - return uri; - } - - /************************************************************************** - * Parses and imports the following XML. - *
      -     * <resourceURLs>
      -     *   <Resource name="Service"         url="..." />
      -     *   <Resource name="Object"          url="..." />
      -     *   <Resource name="Namespace"       url="..." />
      -     *   <Resource name="ServiceInstance" url="..." />
      -     *   <Resource name="Full"            url="..." />
      -     * </resourceURLs>
      -     * 
      - *************************************************************************/ - public MobyResourceRef[] getResourceRefs() - throws MobyException { - - String cacheId = "retrieveResourceURLs"; - MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); - if (cachedResults != null) - return cachedResults; - - String result = (String)doCall ("retrieveResourceURLs", - new Object[] {}); - - // parse returned XML - Vector v = new Vector(); - Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); - NodeList list = document.getElementsByTagName ("Resource"); - for (int i = 0; i < list.getLength(); i++) { - Element elem = (Element)list.item (i); - try { - v.addElement - (new MobyResourceRef (elem.getAttribute ("name"), - new URL ((String)elem.getAttribute ("url")), - elem.getAttribute ("type"))); - } catch (MalformedURLException e2) { - if (debug) - System.err.println ("Bad URL: " + elem.getAttribute ("url")); - } - } - - MobyResourceRef[] results = new MobyResourceRef [v.size()]; - v.copyInto (results); - - // Add this data to the cache in case we get called again - setContents (cacheId, results); - - return results; - } - - /************************************************************************** - * - *************************************************************************/ - public InputStream getResource (String resourceName) - throws MobyException { - - MobyResourceRef[] resourceRefs = getResourceRefs(); - for (int i = 0; i < resourceRefs.length; i++) { - if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { - return Utils.getInputStream (resourceRefs[i].getResourceLocation()); - } - } - throw new MobyException ("No resource found for '" + resourceName + "'."); - } - - /************************************************************************** - * Return a case-insensitive comparator of Strings. It is used to - * create various TreeMaps where keys are strings. - *************************************************************************/ - protected static Comparator getStringComparator() { - return new Comparator() { - public int compare (Object o1, Object o2) { - return ((String)o1).compareToIgnoreCase ((String)o2); - } - }; - } - - // cache URL/URI so we only check once - private static String CHECKED_URL = null; - private static String CHECKED_URI = null; - - /** - * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared - * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods - * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. - * - * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism - */ - public static CentralImpl getDefaultCentral() throws MobyException{ - return getDefaultCentral(null); - } - - public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ - if(reg == null && defaultCentrals.containsKey("")){ - return defaultCentrals.get(""); - } - else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ - return defaultCentrals.get(reg.getEndpoint()); - } - - String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); - if(resURL != null){ - System.err.println("Loading "+resURL); - try{ - LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); - for(String line = reader.readLine(); line != null; line = reader.readLine()){ - if(!line.trim().startsWith("#")){ - className = line.trim(); - break; - } - } - } catch(Exception e){ - logger.log(Level.WARNING, - "Error reading " + resURL, - e); - } - } - try{ - System.err.println("Central class is "+className); - Class clazz = Class.forName(className); - if(reg == null){ // should use default nullary c-tor - defaultCentrals.put("", (CentralImpl) clazz.newInstance()); - } - else{ // should have (String endpoint, String namespace) c-tor - for(Constructor ctor: clazz.getDeclaredConstructors()){ - Class[] params = ctor.getParameterTypes(); - if(params.length == 2 && params[0].getName().equals("java.lang.String") && - params[1].getName().equals("java.lang.String") ){ - defaultCentrals.put(reg.getEndpoint(), - (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); - break; - } - } - if(!defaultCentrals.containsKey(reg.getEndpoint())){ - logger.log(Level.WARNING, - "Could not find required (String endpoint, String namespace)" + - "constructor for class " + className); - } - } - } catch(Exception e){ - logger.log(Level.WARNING, - "Could not load class " + className, - e); - if(reg == null){ - defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. - } - else{ - defaultCentrals.put(reg.getEndpoint(), - new CentralImpl(reg.getEndpoint(), reg.getNamespace())); - } - } - - return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); - } - - /** - * - * @return a String representing the Default mobycentral endpoint. If the - * system property 'moby.check.default' exists and is set to true, - * then the URL http://biomoby.org/mobycentral is queried and the - * default central endpoint is returned, otherwise DEFAULT_ENDPOINT - * is returned. - */ - public static String getDefaultURL() { - boolean check = false; - try { - check = Boolean.getBoolean("moby.check.default"); - } catch (Exception e) { - - } - - if (check) { - // return the last checked url if we have done this before - if (CHECKED_URL != null && CHECKED_URL.trim() != "") { - return CHECKED_URL; - } - - // create a HttpClient object - HttpClient client = new HttpClient(); - // set up the Head method - HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); - // do not follow redirects or we will get a 411 error - method.setFollowRedirects(false); - // retry 3 times - method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); - // set the user agent ... should probably make this something more reasonable - method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); - try { - // Execute the method. - int statusCode = client.executeMethod(method); - - if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { - System.err.println("Method failed: " - + method.getStatusLine()); - } else { - try { - String location = method.getResponseHeader("location").getValue(); - CHECKED_URL = location; - try { - CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; - } catch (MalformedURLException murle ) { - CHECKED_URI = DEFAULT_NAMESPACE; - } - return CHECKED_URL; - } catch (NullPointerException npe) { - return DEFAULT_ENDPOINT; - } - } - } catch (HttpException e) { - System.err.println("Fatal protocol violation: " - + e.getMessage()); - e.printStackTrace(); - } catch (IOException e) { - System.err.println("Fatal transport error: " + e.getMessage()); - e.printStackTrace(); - } finally { - // Release the connection. - method.releaseConnection(); - } - - } else { - return DEFAULT_ENDPOINT; - } - return DEFAULT_ENDPOINT; - } - - /** - * - * @return a String representing the default mobycentral uri. If the - * system property 'moby.check.default' exists and is set to true, - * then the URL http://biomoby.org/mobycentral is queried and the - * default central namespace is returned, otherwise DEFAULT_NAMESPACE - * is returned. - */ - public static String getDefaultURI() { - boolean check = false; - try { - check = Boolean.getBoolean("moby.check.default"); - } catch (Exception e) { - - } - if (check) { - if (CHECKED_URI != null && CHECKED_URI.trim() != "") { - return CHECKED_URI; - } - // need to check ... - getDefaultURL(); - return CHECKED_URI; - } else { - return DEFAULT_NAMESPACE; - } - } - /************************************************************************** - * Convert non-suitable characters in a XML string into their - * entity references.

      - * - * Adapted from jDom. - * - * @param str input to be converted - * @return If there were any non-suitable characters, return a new - * string with those characters escaped, otherwise return the - * unmodified input string - * - *************************************************************************/ - public String escapeXML (String str) { - StringBuffer buffer = null; - char ch; - String entity; - for (int i = 0; i < str.length(); i++) { - ch = str.charAt (i); - switch (ch) { - case '<' : - entity = "<"; - break; - case '>' : - entity = ">"; - break; - case '&' : - entity = "&"; - break; - default : - entity = null; - break; - } - if (buffer == null) { - if (entity != null) { - // An entity occurred, so we'll have to use StringBuffer - // (allocate room for it plus a few more entities). - buffer = new StringBuffer (str.length() + 20); - // Copy previous skipped characters and fall through - // to pickup current character - buffer.append (str.substring (0, i)); - buffer.append (entity); - } - } else { - if (entity == null) { - buffer.append (ch); - } else { - buffer.append (entity); - } - } - } - - // If there were any entities, return the escaped characters - // that we put in the StringBuffer. Otherwise, just return - // the unmodified input string. - return (buffer == null) ? str : buffer.toString(); - } - - /************************************************************************* - * Format an exception. - *************************************************************************/ - public static String formatFault (AxisFault e, String endpoint, QName method) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - formatFault (e, new PrintStream (baos), endpoint, method); - return baos.toString(); - } - - /************************************************************************* - * Format an exception. - *************************************************************************/ - public static void formatFault (AxisFault e, PrintStream out, - String endpoint, QName method) { - - out.println ("===ERROR==="); - out.println ("Fault details:"); - // for some obvious errors I do not print all details (with a lenghty trace stack) - String faultString = e.getFaultString(); - if ( (! faultString.startsWith ("java.net.ConnectException")) && - (faultString.indexOf ("Could not find class for the service named:") == -1) - ) { - org.w3c.dom.Element[] details = e.getFaultDetails(); - for (int i = 0; i < details.length; i++) { - String s = details[i].toString().replaceAll ("<", "<"); - s = s.replaceAll (">", ">"); - out.println (s); - } - } - out.println ("Fault string: " + faultString); - out.println ("Fault code: " + e.getFaultCode()); - out.println ("Fault actor: " + e.getFaultActor()); - if (endpoint != null || method != null) - out.println ("When calling:"); - if (endpoint != null) - out.println ("\t" + endpoint); - if (method != null) - out.println ("\t" + method); - out.println ("==========="); - } - - -} +// CentralImpl.java +// A default client to the Moby Central service. +// +// senger at ebi.ac.uk +// February 2003 +// + +package org.biomoby.client; + +import org.biomoby.registry.meta.Registry; +import org.biomoby.shared.Central; +import org.biomoby.shared.MobyData; +import org.biomoby.shared.MobyDataType; +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyNamespace; +import org.biomoby.shared.MobyPrimaryDataSet; +import org.biomoby.shared.MobyPrimaryDataSimple; +import org.biomoby.shared.MobyRelationship; +import org.biomoby.shared.MobySecondaryData; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.MobyServiceType; +import org.biomoby.shared.NoSuccessException; +import org.biomoby.shared.PendingCurationException; +import org.biomoby.shared.MobyResourceRef; +import org.biomoby.shared.Utils; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.namespace.QName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.apache.axis.AxisFault; +import org.apache.axis.client.Call; +import org.apache.axis.client.Service; +import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.HeadMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PrintStream; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; +import java.util.TreeMap; +import java.util.Comparator; +import java.util.zip.GZIPInputStream; +import java.util.logging.*; + +/** + * A default implementation of the + * interface {@link org.biomoby.shared.Central Central} + * allowing access to a Moby registry. + *

      + * This class is supposed to be used by all other clients that wish + * to communicate with the Moby Registry, but do not want to know + * about all XML details that are necessary for talking with the Moby Central + * directly. This is an example of a client program: + *

      + * import org.biomoby.shared.Central;
      + * import org.biomoby.shared.MobyException;
      + * import org.biomoby.client.CentralImpl;
      + * import java.util.Map;
      + * import java.util.Iterator;
      + *
      + * public class Test {
      + *
      + *    public static void main (String[] args)
      + *       throws MobyException {
      + *
      + *       Central worker = new CentralImpl();
      + *       Map authorities = worker.getServiceNamesByAuthority();
      + *
      + *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
      + *          Map.Entry entry = (Map.Entry)it.next();
      + *          System.out.println (entry.getKey());
      + *          String[] names = (String[])entry.getValue();
      + *          for (int i = 0; i < names.length; i++)
      + *             System.out.println ("\t" + names[i]);
      + *       }
      + *    }
      + * }
      + *
      + * + * @author Martin Senger + * @version $Id$ + */ + +public class CentralImpl + implements Central, SimpleCache { + + private URL endpoint; + private String uri; + protected boolean debug = false; + + /** Common central used to if getDefaultCentral() is called */ + protected static Map defaultCentrals = new HashMap(); + + /** Default location (endpoint) of a Moby registry. */ + public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; + + /** Default namespace used by the contacted Moby registry. */ + public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; + + /** + * The META-INF resource file that will be checked to determine what + * default class should be instantiated in order to create a Central Implementation + * when getDefaultCentral() is called. + */ + public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; + /** The class to use for getDefaultCentral if all else fails */ + public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; + private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); + + /** + * Thread local that gives each thread its own + * DocumentBuilderFactory (since it is not thread-safe). Code taken + * from Apache's JaxpUtils. + */ + public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { + protected synchronized Object initialValue() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware (true); + return dbf; + } + }; + + + /************************************************************************* + * Default constructor. It connects to a default Moby registry + * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace + * (as defined int {@link #DEFAULT_NAMESPACE}). + *************************************************************************/ + public CentralImpl() + throws MobyException { + this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry to use. + * + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser is available + *************************************************************************/ + public CentralImpl (String endpoint) + throws MobyException { + this (endpoint, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry and what + * namespace to use. If any of the parameters is null, its default + * value is used instead. + *

      + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser was found + *************************************************************************/ + public CentralImpl (String endpoint, String namespace) + throws MobyException { + + if (endpoint == null || "".equals (endpoint.trim())) + endpoint = DEFAULT_ENDPOINT; + if (namespace == null || "".equals (namespace.trim())) + namespace = DEFAULT_NAMESPACE; + + try { + this.endpoint = new URL (endpoint); + } catch (MalformedURLException e) { + throw new MobyException ("Bad URL: " + endpoint); + } + this.uri = namespace; + + cache = new Hashtable(); + useCache = true; + } + + /************************************************************************* + * Loads a DOM Document from an InputStream. Uses thread-safe + * mechanism. + *************************************************************************/ + public static Document loadDocument (InputStream input) + throws MobyException { + try { + DocumentBuilderFactory dbf + = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); + DocumentBuilder db = dbf.newDocumentBuilder(); + return (db.parse (input)); + } catch (Exception e) { + throw new MobyException ("Problem with reading XML input: " + e.toString(), e); + } + } + + /************************************************************************* + * Call 'method' with 'parameters' and return its result. + *************************************************************************/ + protected Object doCall (String method, Object[] parameters) + throws MobyException { + + Call call = null; + try { + Service service = new Service(); + call = (Call) service.createCall(); + call.setTargetEndpointAddress (endpoint); + call.setTimeout (new Integer (0)); + + call.setSOAPActionURI (uri + "#" + method); + + if (debug) { + System.err.println ("METHOD CALL: " + method); + System.err.println ("------------"); + if (parameters.length > 0) + System.err.println (parameters[0] + "\n"); + System.err.println ("------------\n"); + + Object result = call.invoke (uri, method, parameters); + + System.err.println ("METHOD RETURN:"); + System.err.println ("------------"); + if (result != null) + System.err.println (result + "\n"); + System.err.println ("------------\n"); + + return resultToString (result); + + } else { + return resultToString (call.invoke (uri, method, parameters)); + } + + } catch (AxisFault e) { + throw new MobyException + (formatFault (e, + endpoint.toString(), + (call == null ? null : call.getOperationName())), + e); +// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); + + } catch (Exception e) { + throw new MobyException (e.toString(), e); +// e.printStackTrace(); + } + } + + + /************************************************************************** + * Parse the given XML sniplet to find tag 'success'. If it has value '1' + * look further for tag 'id' and return it back (or return an empty string + * if ID is not there). Otherwise raise an exception with the 'culprit' + * and with the message from the tag 'message'.

      + * + * The return value is a two-element long array. The first element + * is the ID (given by BioMobe registry), and the second element + * is RDF corresponding with the registered object (BioMoby + * returns this only for service instances, so for other objects + * this will be null).

      + * + * This is how the XML is supposed to look: + * + * + * + * + * + * + * + * Success takes the value "1" to indicate success, "0" to + * indicate failure, and "-1" to indicate "Pending Curation". + *************************************************************************/ + protected String[] checkRegistration (String xml, Object culprit) + throws MobyException, NoSuccessException, PendingCurationException { + + String id = "", success = "0", message = "", rdf = ""; + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + Element root = document.getDocumentElement(); + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item (i).getNodeType() != Node.ELEMENT_NODE) + continue; + Element elem = (Element)children.item (i); + if (elem.getNodeName().equals ("id")) { + if (elem.getFirstChild() != null) + id = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals("success")) { + if (elem.getFirstChild() != null) + success = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("message")) { + if (elem.getFirstChild() != null) + message = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("RDF")) { + if (elem.getFirstChild() != null) + rdf = elem.getFirstChild().getNodeValue(); + } + } + + if (success.equals ("0")) + throw new NoSuccessException (message, culprit); + else if (success.equals ("-1")) + throw new PendingCurationException(); + return new String[] { id, rdf }; + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildPrimaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryInputs = service.getPrimaryInputs(); + buf.append ("\n"); + for (int i = 0; i < primaryInputs.length; i++) + buf.append (primaryInputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * secondary are included. Note that the main job of converting to XML is + * done by instances of MobySecondaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildSecondaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] secInputs = service.getSecondaryInputs(); + buf.append ("\n"); + for (int i = 0; i < secInputs.length; i++) { + buf.append (secInputs[i].toXML()); + } + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing output + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + * + *************************************************************************/ + protected String buildOutputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryOutputs = service.getPrimaryOutputs(); + buf.append ("\n"); + for (int i = 0; i < primaryOutputs.length; i++) + buf.append (primaryOutputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML represented a query object (an object used + * to find a service). + * + * The returned XML looks like this: + * + * + * + * + * + * + * + * + * + * + * + * ServiceTypeTerm + * ServiceName + * moby + * http://desired.service.provider; + * 1|0 + * 1|0 + * 1|0 + * + * something + * .... + * .... + * + *************************************************************************/ + protected String buildQueryObject (MobyService service, + String[] keywords, + boolean expandObjects, + boolean expandServices, + boolean authoritative) { + if (service == null) { + service = new MobyService ("dummy"); + service.setCategory (""); + } + StringBuffer buf = new StringBuffer(); + + buf.append ("\n\n"); + MobyData[] pi = service.getPrimaryInputs(); + if (pi.length > 0) { + for (int i = 0; i < pi.length; i++) + buf.append (pi[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("\n\n"); + MobyData[] po = service.getPrimaryOutputs(); + if (po.length > 0) { + for (int i = 0; i < po.length; i++) + buf.append (po[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("" + service.getType() + "\n"); + + String name = service.getName(); + if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) + buf.append ("" + service.getName() + "\n"); + + String sigURL = service.getSignatureURL(); + if (!sigURL.equals ("")) + buf.append ("" + sigURL + "\n"); + + buf.append ("" + service.getCategory() + "\n"); + buf.append ("" + service.getAuthority() + "\n"); + + buf.append (""); + buf.append (expandObjects ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (expandServices ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (authoritative ? "1" : "0"); + buf.append ("\n"); + + buf.append ("\n"); + if (keywords != null && keywords.length > 0) { + for (int i = 0; i < keywords.length; i++) { + buf.append (""); + buf.append (keywords[i]); + buf.append ("\n"); + } + } + buf.append ("\n"); + + return new String (buf); + } + + /************************************************************************** + * Extract one or more MobyService objects from the given XML piece. + * The XML should look like this: + *

      +     *  <Services>
      +     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
      +     *      <serviceType>Service_Ontology_Term</serviceType>
      +     *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
      +     *      <contactEmail>your at email.addy.here</contactEmail>
      +     *      <signatureURL>http://service.RDF.here</signatureURL>
      +     *      <URL>http://service.endpoint.here/scriptname</URL>
      +     *      <authoritative>1</authoritative>
      +     *      <Input>
      +     *           <!-- one or more Simple and/or Complex Primary articles -->
      +     *      </Input>
      +     *      <Output>
      +     *           <!-- one or more Simple and/or Complex Primary articles --> 
      +     *      </Output>
      +     *      <secondaryArticles>
      +     *           <!-- one or more Secondary articles -->
      +     *      </secondaryArticles>
      +     *      <Description><![CDATA[free text description here]]></Description>
      +     *    </Service>
      +     *    ...  <!--  one or more Service blocks may be returned -->
      +     *    ...
      +     *    ...
      +     *  </Services>
      +     * 
      + * @throws MobyException if the XML document is invalid + *************************************************************************/ + public MobyService[] extractServices (String xml) + throws MobyException { + + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + NodeList list = document.getElementsByTagName ("Service"); + MobyService[] results = new MobyService [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyService service = new MobyService (elem.getAttribute ("serviceName")); + service.setAuthority (elem.getAttribute ("authURI")); + service.setLSID (elem.getAttribute ("lsid")); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + service.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Category")) { + service.setCategory (getFirstValue (children.item (j))); + } else if (nodeName.equals ("URL")) { + service.setURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("signatureURL")) { + service.setSignatureURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + service.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("serviceType")) { + service.setType (getFirstValue (children.item (j))); + MobyServiceType mst = new MobyServiceType(service.getType()); + NamedNodeMap map = (children.item (j).getAttributes()); + if (map != null) { + Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); + if (node != null) + mst.setLSID(node.getNodeValue()); + } + service.setServiceType(mst); + } else if (nodeName.equals ("authoritative")) { + String authoritative = getFirstValue (children.item (j)); + service.setAuthoritative (authoritative.equals ("1") ? true : false); + } else if (nodeName.equals ("Input")) { + // + // + // + // ... + // + // + // ...... + // ...... + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addInput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addInput (data); + } + } + } else if (nodeName.equals ("Output")) { + // + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addOutput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addOutput (data); + } + } + + } else if (nodeName.equals ("secondaryArticles")) { + // + // ... + // + NodeList parameters = children.item (j).getChildNodes(); + for (int k = 0; k < parameters.getLength(); k++) { + if (parameters.item (k).getNodeName().equals ("Parameter")) { + MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); + service.addInput (data); + } + } + } + } + results [i] = service; + } + return results; + } + + // protect against null values + protected String getFirstValue (Node child) { + Node node = child.getFirstChild(); + if (node == null) return ""; + String value = node.getNodeValue(); + if (value == null) return ""; + return value; + } + + protected String getFirstValue (NodeList children) { + if (children.item(0) != null && children.item(0).hasChildNodes()) { + children.item(0).normalize(); + return getFirstValue (children.item(0)); + } + return ""; + } + + /************************************************************************** + * + * Implementing SimpleCache interface. + * + * Why to have an interface for such trivial thing? Well, because + * I needed to overwrite the caching mechanism in the subclasses + * so I needed to have all caching functions as separate methods - + * that's why I have collect them in an interface. + * + *************************************************************************/ + private Hashtable cache; // this is the cache itself + private boolean useCache; // this signal that we are actually caching things + + // not used here + public String createId (String rootName, + String semanticType, String syntaxType, + long lastModified, + Properties props) { + return ""; // not used here + } + + // check existence of a cached object + public boolean existsInCache (String id) { + synchronized (cache) { + if (useCache) return cache.containsKey (id); + else return false; + } + } + + // retrieve from cache + public Object getContents (String id) { + synchronized (cache) { + if (useCache) return cache.get (id); + else return null; + } + } + + // cache an object + public void setContents (String id, java.lang.Object data) { + synchronized (cache) { + if (useCache) cache.put (id, data); + } + } + + // in this implementation, it clears the whole cache, regardless + // what 'id' is passed + public void removeFromCache (String id) { + cache.clear(); + } + + /************************************************************************** + * + * And the other methods related to caching (but not part of the + * SimpleCache interface). + * + **************************************************************************/ + + /************************************************************************** + * By default, caching is enabled to reduce network traffic. + * Setting this to false will clear the cache, and not cache any + * further calls unless it is set to true again.

      + * + * @param shouldCache whether retrieveXXX call results should be + * cached in case they are called again (i.e. don't request + * MobyCentral every time) + **************************************************************************/ + public void setCacheMode (boolean shouldCache) { + useCache = shouldCache; + if (! useCache) + removeFromCache (null); + } + + /************************************************************************** + * Find if caching is currently enabled. + * + * @return true if caching is enabled + **************************************************************************/ + public boolean getCacheMode(){ + return useCache; + } + + /************************************************************************** + * Parses and imports the following XML. + *

      +     * <serviceNames>
      +     *   <serviceName name="serviceName" authURI='authority.info.here'/>
      +     *   ...
      +     *   ...
      +     * </serviceNames>
      +     * 
      + * + * @deprecated Replaced by {@link + * #getServiceNamesByAuthority}. The reason is that this method + * returns a random result if there are more services with the + * same name but belonging to different authorities.

      + * + *************************************************************************/ + public Map getServiceNames() + throws MobyException { + + String result = (String)doCall ("retrieveServiceNames", + new Object[] {}); + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + results.put (elem.getAttribute ("name"), + elem.getAttribute ("authURI")); + } + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *

      +     * <serviceNames>
      +     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
      +     *   ...
      +     *   ...
      +     * </serviceNames>
      +     * 
      + * + * @return a Map which has authorities as keys, and String arrays + * with service names as a values. + *************************************************************************/ + public Map getServiceNamesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, true); + } + + /************************************************************************** + * Similar to {@link #getServiceNamesByAuthority} but the + * resulting Map contains slightly more.

      + * + * @return a Map which has authorities as keys, and arrays of + * MobyServices as a values. Each MobyService is filled with its + * name, authority and LSID. + *************************************************************************/ + public Map getServicesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, false); + } + + // + protected String getServiceNamesByAuthorityAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceNames", + new Object[] {}); + } + + // if onlyNames == true + // Map: authority name -> String[] + // (filled with service namea) + // else + // Map: authority name -> MobyService[] + // (filled with service name, authority and lsid) + protected Map createServicesByAuthorityFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + String auth = elem.getAttribute ("authURI"); + Vector v = + (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); + if (onlyNames) { + v.addElement (name); + } else { + MobyService ms = new MobyService (name); + ms.setAuthority (auth); + ms.setLSID (elem.getAttribute ("lsid")); + v.addElement (ms); + } + results.put (auth, v); + } + + // change values of type Vector to MobyService[] or String[] + for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + Vector v = (Vector)entry.getValue(); + if (onlyNames) { + String[] sNames = new String [v.size()]; + v.copyInto (sNames); + entry.setValue (sNames); + } else { + MobyService[] mss = new MobyService [v.size()]; + v.copyInto (mss); + entry.setValue (mss); + } + } + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     *  <serviceProviders>
      +     *     <serviceProvider name="authority.URI.here"/>
      +     *          ...
      +     *          ...
      +     *  </serviceProviders>
      +     * 
      + *************************************************************************/ + public String[] getProviders() + throws MobyException { + + String cacheId = "retrieveServiceProviders"; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveServiceProviders", + new Object[] {}); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceProvider"); + String[] results = new String [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) + results[i] = ((Element)list.item (i)).getAttribute ("name"); + + // Add this data to the cache in case we get called again + setContents (cacheId, results); + + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     *  <serviceTypes>
      +     *     <serviceType name="serviceName" lsid="...">
      +     *            <Description><![CDATA[free text description here]]></Description>
      +     *            <contactEmail>...</contactEmail>
      +     *            <authURI>...</authURI>
      +     *     </serviceType>
      +     *          ...
      +     *          ...
      +     *  </serviceTypes>
      +     * 
      + *************************************************************************/ + public Map getServiceTypes() + throws MobyException { + String result = getServiceTypesAsXML(); + Map results = new TreeMap (getStringComparator()); + MobyServiceType[] types = createServiceTypesFromXML (result); + for (int i = 0; i < types.length; i++) { + results.put (types[i].getName(), + types[i].getDescription()); + } + return results; + } + + // + protected String getServiceTypesAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceTypes", + new Object[] {}); + } + + // but be aware that the created MobyServiceTypes are not complete + // - they do not have the relationship information; that's why + // this method is not public; the full service types are available + // from CentralDigest implementations + protected MobyServiceType[] createServiceTypesFromXML (String result) + throws MobyException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceType"); + if (list == null || list.getLength() == 0) + return new MobyServiceType[] {}; + MobyServiceType[] results = new MobyServiceType [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); + st.setLSID (elem.getAttribute ("lsid")); + st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = st; + } + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     *  <Namespaces>
      +     *     <Namespace name="namespace" lsid="...">
      +     *            <Description><![CDATA[free text description here]]></Description>
      +     *            <contactEmail>...</contactEmail>
      +     *            <authURI>...</authURI>
      +     *     </Namespace>
      +     *          ...
      +     *          ...
      +     *  </Namespaces>
      +     * 
      + *************************************************************************/ + public MobyNamespace[] getFullNamespaces() + throws MobyException { + + String result = getNamespacesAsXML(); + return createNamespacesFromXML (result); + } + + // + protected String getNamespacesAsXML() + throws MobyException { + return (String)doCall ("retrieveNamespaces", + new Object[] {}); + } + + // + protected MobyNamespace[] createNamespacesFromXML (String result) + throws MobyException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); + if (list == null || list.getLength() == 0) { + return new MobyNamespace[] {}; + } + MobyNamespace[] results = new MobyNamespace [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); + nm.setLSID (elem.getAttribute ("lsid")); + nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = nm; + } + + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * + * @deprecated Replaced by {@link #getFullNamespaces} that gives + * more information for the same price.

      + *************************************************************************/ + public Map getNamespaces() + throws MobyException { + + Map results = new TreeMap (getStringComparator()); + MobyNamespace[] namespaces = getFullNamespaces(); + for (int i = 0; i < namespaces.length; i++) { + results.put (namespaces[i].getName(), + namespaces[i].getDescription()); + } + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *

      +     *  <objectNames>
      +     *     <Object name="objectName" lsid="...">
      +     *            <Description><![CDATA[free text description here]]></Description>
      +     *     </Object>
      +     *          ...
      +     *          ...
      +     *  </objectNames>
      +     * 
      + *************************************************************************/ + public Map getDataTypeNames() + throws MobyException { + String result = getDataTypeNamesAsXML(); + return createDataTypeNamesFromXML (result, true); + } + + // + protected String getDataTypeNamesAsXML() + throws MobyException { + return (String)doCall ("retrieveObjectNames", + new Object[] {}); + } + + // if onlyNames == true + // Map: data type name -> description (String) + // else + // Map: data type name -> MobyDataType[] + // (filled with name, description, and lsid) + protected Map createDataTypeNamesFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Object"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + if (name == null) + continue; // ignore no-named data types + String desc = ""; + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("Description")) { + desc = getFirstValue (children.item (j)); + break; + } + } + if (onlyNames) { + results.put (name, desc); + } else { + MobyDataType dt = new MobyDataType (name); + dt.setDescription (desc); + dt.setLSID (elem.getAttribute ("lsid")); + results.put (name, dt); + } + } + return results; + } + + + /************************************************************************** + * Parses and imports the following XML. An example: + * + *
      +     * <retrieveObjectDefinition>
      +     *   <objectType lsid="...">go_term</objectType>
      +     *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
      +     *   <authURI>http://www.illuminae.com</authURI>
      +     *   <contactEmail>markw at illuminae.com</contactEmail>
      +     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      +     *      <objectType articleName=''>urn:lsid:biomoby.org:objectclass:object</objectType>
      +     *   </Relationship>
      +     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
      +     *      <objectType articleName='Term'>urn:lsid:biomoby.org:objectclass:string</objectType>
      +     *      <objectType articleName='Definition'>urn:lsid:biomoby.org:objectclass:string</objectType>
      +     *   </Relationship>
      +     *   <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:has'>
      +     *      <objectType articleName='Problems'>urn:lsid:biomoby.org:objectclass:string</objectType>
      +     *      <objectType articleName='Issues'>urn:lsid:biomoby.org:objectclass:string</objectType>
      +     *   </Relationship>
      +     * </retrieveObjectDefinition>
      +     * 
      + *************************************************************************/ + public MobyDataType getDataType (String dataTypeName) + throws MobyException, NoSuccessException { + + String result = getDataTypeAsXML (dataTypeName); + return createDataTypeFromXML (result, dataTypeName); + } + + public MobyDataType[] getDataTypes() + throws MobyException, NoSuccessException { + Map datatypeMap = getDataTypeNames(); + MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; + int i = 0; + for(String dataTypeName: datatypeMap.keySet()){ + datatypes[i++] = getDataType(dataTypeName); + } + return datatypes; + } + + protected String getDataTypeAsXML (String dataTypeName) + throws MobyException, NoSuccessException { + + return (String)doCall ("retrieveObjectDefinition", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + }); + } + + protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) + throws MobyException, NoSuccessException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); + NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); + if (list == null || list.getLength() == 0) + throw new NoSuccessException ("Data Type name was not found.", + dataTypeName); + MobyDataType data = null; + Element elem = (Element)list.item (0); + NodeList children = elem.getChildNodes(); + + // first find the "real" (LSID-ized) data type name + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("objectType")) { + data = new MobyDataType (getFirstValue (children.item (j))); + data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); + break; + } + } + + // if not found (unprobable) use the name given by the caller + if (data == null) + data = new MobyDataType (dataTypeName); + + // now fill the data type object with the rest of attributes + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + data.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("authURI")) { + data.setAuthority (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + data.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Relationship")) { + String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); + if (relationshipType.endsWith ("isa")) { + + NodeList parents = children.item (j).getChildNodes(); + for (int k = 0; k < parents.getLength(); k++) { + if (parents.item (k).getNodeName().equals ("objectType")) { + data.addParentName (getFirstValue (parents.item (k))); + } + } + } else if (relationshipType.endsWith ("hasa")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + getFirstValue (belows.item (k)), + Central.iHASA ); + } + } + } else if (relationshipType.endsWith ("has")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + belows.item (k).getFirstChild().getNodeValue(), + Central.iHAS ); + } + } + } + } + } + return data; + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName) + throws MobyException, NoSuccessException { + + Map names = getServiceNames(); + + for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + if ( ((String)entry.getKey()).equals (serviceName) ) + return getServiceWSDL (serviceName, (String)entry.getValue()); + } + + throw new NoSuccessException ("Service not found.", serviceName); + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName, String authority) + throws MobyException, NoSuccessException { + + String cacheId = "getServiceWSDL" + serviceName + ":" + authority; + String cachedResults = (String)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("retrieveService", + new Object[] { + "" + + "" + + "" + }); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + Element service = document.getDocumentElement(); + Node wsdl = service.getFirstChild(); + if (wsdl == null) + throw new NoSuccessException ("Service not found OR WSDL is not available.", + serviceName + " (" + authority + ")"); + + String results = wsdl.getNodeValue(); + setContents (cacheId, results); + return results; + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterDataTypeXML (MobyDataType dataType) { + + // build the ISA tag (expressing hierarchy of data types) + String[] names = dataType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + // build the HASA/HAS tags (expressing containments of data types) + MobyRelationship[] children = dataType.getChildren(); + StringBuffer buf2 = new StringBuffer(); // for HASA + StringBuffer buf3 = new StringBuffer(); // for HAS + for (int i = 0; i < children.length; i++) { + if (children[i].getRelationshipType() == Central.iHASA) { + buf2.append (""); + buf2.append (children[i].getDataTypeName()); + buf2.append (""); + } else if (children[i].getRelationshipType() == Central.iHAS) { + buf3.append (""); + buf3.append (children[i].getDataTypeName()); + buf3.append (""); + } + } + + return + "" + + "" + dataType.getName() + "" + + "" + + "" + + "" + new String (buf) + + "" + + "" + new String (buf2) + + "" + + "" + new String (buf3) + + "" + + "" + dataType.getAuthority() + "" + + "" + dataType.getEmailContact() + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerObjectClass", + new Object[] { getRegisterDataTypeXML (dataType) }); + dataType.setId (checkRegistration (result, dataType)[0]); + } + + /************************************************************************* + * B + *************************************************************************/ + public void unregisterDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterObjectClass", + new Object[] { + "" + + "" + dataType.getName() + "" + + "" + }); + checkRegistration (result, dataType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceTypeXML (MobyServiceType serviceType) { + + // build the ISA tag (expressing hierarchy of service types) + String[] names = serviceType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + return + "" + + "" + serviceType.getName() + "" + + "" + serviceType.getEmailContact() + "" + + "" + serviceType.getAuthority() + "" + + "" + + "" + + "" + new String (buf) + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerServiceType", + new Object[] { getRegisterServiceTypeXML (serviceType) }); + serviceType.setId (checkRegistration (result, serviceType)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterServiceType", + new Object[] { + "" + + "" + serviceType.getName() + "" + + "" + }); + checkRegistration (result, serviceType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterNamespaceXML (MobyNamespace namespace) { + return + "" + + "" + namespace.getName() + "" + + "" + namespace.getEmailContact() + "" + + "" + namespace.getAuthority() + "" + + "" + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("registerNamespace", + new Object[] { getRegisterNamespaceXML (namespace) }); + namespace.setId (checkRegistration (result, namespace)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterNamespace", + new Object[] { + "" + + "" + namespace.getName() + "" + + "" + }); + checkRegistration (result, namespace); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceXML (MobyService service) { + return + "" + + "" + service.getCategory() + "" + + "" + service.getName() + "" + + "" + service.getType() + "" + + "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + + "" + service.getAuthority() + "" + + "" + escapeXML (service.getSignatureURL()) + "" + + "" + escapeXML (service.getURL()) + "" + + "" + service.getEmailContact() + "" + + "" + (service.isAuthoritative() ? "1" : "0") + "" + + "" + + "" + + buildPrimaryInputTag (service) + + buildSecondaryInputTag (service) + + buildOutputTag (service) + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerService", + new Object[] { getRegisterServiceXML (service) }); + String[] registered = checkRegistration (result, service); + service.setId (registered [0]); + service.setRDF (registered [1]); + String pathToRDF = service.getPathToRDF(); + if ( ! pathToRDF.equals ("") ) { + File fileRDF = new File (pathToRDF); + try { + PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); + fileout.println (registered [1]); + fileout.close(); + } catch (IOException e) { + StringBuffer buf = new StringBuffer (100); + buf.append ("Failed to save RDF in '"); + buf.append (fileRDF.getAbsolutePath() + "'. "); + buf.append (e.toString()); + try { + File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); + PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); + fileout.println (registered [1]); + fileout.close(); + buf.append ("\nReturned RDF file was therefore stored in: "); + buf.append (tmpFile.getAbsolutePath()); + } catch (IOException e2) { + buf.append ("\nEven saving in a temporary file failed: "); + buf.append (e2.toString()); + } + throw new MobyException (buf.toString()); + } + } + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterService", + new Object[] { + "" + + "" + service.getAuthority() + "" + + "" + service.getName() + "" + + "" + }); + checkRegistration (result, service); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String serviceType) + throws MobyException { + if (serviceType == null) + return new MobyService[] {}; + MobyService pattern = new MobyService ("dummy"); + pattern.setCategory (""); + pattern.setType (serviceType); + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String[] keywords) + throws MobyException { + if (keywords == null) + return new MobyService[] {}; + return findService (null, keywords); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern) + throws MobyException { + if (pattern == null) + return new MobyService[] {}; + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords) + throws MobyException { + return findService (pattern, keywords, true, true); + } + + /************************************************************************** + * All 'findService' methods end up here. + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + if (pattern == null) { + pattern = new MobyService ("dummy"); + pattern.setCategory (""); + } + + String result = + getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); + MobyService[] services = extractServices (result); + return services; + } + + // ...actually all 'findService' methods end up here + protected String getServicesAsXML (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + String[] query = new String[] { + "" + + buildQueryObject (pattern, keywords, + includeParentDataTypes, + includeChildrenServiceTypes, + false) + + "" + }; + return (String)doCall ("findService", query); + } + + /************************************************************************** + * + *************************************************************************/ + public String call (String methodName, String inputXML) + throws MobyException { + Object result; + if (inputXML == null || inputXML.equals ("")) + result = doCall (methodName, new Object[] { }); + else + result = doCall (methodName, new Object[] { inputXML }); + return (String)result; + } + + /************************************************************************** + * + *************************************************************************/ + protected static String resultToString (Object result) + throws MobyException { + if (result == null) + throw new MobyException ("Returned result is null."); + if (result instanceof String) + return (String)result; + if (result instanceof String[]) { + String[] tmp = (String[])result; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < tmp.length; i++) + buf.append (tmp[i]); + return new String (buf); + } + if (result instanceof byte[]) + return new String ((byte[])result); + + throw new MobyException ("Unknown type of result: " + result.getClass().getName()); + } + + /************************************************************************** + * + *************************************************************************/ + public boolean setDebug (boolean enabled) { + boolean oldMode = debug; + debug = enabled; + return oldMode; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     * <Relationships>
      +     *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
      +     *     <serviceType>urn:lsid:biomoby.org:servicetype:analysis</serviceType>
      +     *     <serviceType>urn:lsid:biomoby.org:servicetype:service</serviceType>
      +     *   </Relationship>
      +     * </Relationships>
      +     * 
      + *************************************************************************/ + public String[] getServiceTypeRelationships (String serviceTypeName, + boolean expand) + throws MobyException { + String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); + return createServiceTypeRelationshipsFromXML (result); + } + + // + protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, + boolean expand) + throws MobyException { + return + (String)doCall ("Relationships", + new Object[] { + "" + + "" + serviceTypeName + "" + + "" + Central.ISA + "" + + "" + (expand ? "1" : "0") + "" + + "" + }); + } + + // + protected String[] createServiceTypeRelationshipsFromXML (String result) + throws MobyException { + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("serviceType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + } + String[] results = new String [v.size()]; + v.copyInto (results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     *<Relationships>
      +     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
      +     *  </Relationship>
      +     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:hasa'>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
      +     *  </Relationship>
      +     *</Relationships>
      +     * 
      + * + * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an + * attributes 'lsid' and 'articleName' in <objectType> element. + *************************************************************************/ + public Map getDataTypeRelationships (String dataTypeName) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName; + Map cachedResults = (Map)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + Central.ISA + "" + + "" + Central.HASA + "" + + "" + Central.HAS + "" + + "1" + + "" + }); + + // parse returned XML + Map results = new HashMap(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String relType = elem.getAttribute ("relationshipType"); + NodeList children = elem.getChildNodes(); + Vector v = new Vector(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + String[] names = new String [v.size()]; + v.copyInto (names); + results.put (relType, names); + } + + setContents (cacheId, results); + return results; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     *<Relationships>
      +     *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
      +     *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
      +     *  </Relationship>
      +     *</Relationships>
      +     * 
      + *************************************************************************/ + public String[] getDataTypeRelationships (String dataTypeName, + String relationshipType) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + relationshipType + "" + + "1" + + "" + }); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + // it should always be just one element in this list + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } + } + } + String[] results = new String [v.size()]; + v.copyInto (results); + + setContents (cacheId, results); + return results; + } + +// /************************************************************************** +// * +// *************************************************************************/ +// public MobyRelationship[] getRelationships (String dataTypeName) +// throws MobyException { +// return null; +// } + + + /************************************************************************** + * + *************************************************************************/ + public String getRegistryEndpoint() { + return endpoint.toString(); + } + + /************************************************************************** + * + *************************************************************************/ + public String getRegistryNamespace() { + return uri; + } + + /************************************************************************** + * Parses and imports the following XML. + *
      +     * <resourceURLs>
      +     *   <Resource name="Service"         url="..." />
      +     *   <Resource name="Object"          url="..." />
      +     *   <Resource name="Namespace"       url="..." />
      +     *   <Resource name="ServiceInstance" url="..." />
      +     *   <Resource name="Full"            url="..." />
      +     * </resourceURLs>
      +     * 
      + *************************************************************************/ + public MobyResourceRef[] getResourceRefs() + throws MobyException { + + String cacheId = "retrieveResourceURLs"; + MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveResourceURLs", + new Object[] {}); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Resource"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + try { + v.addElement + (new MobyResourceRef (elem.getAttribute ("name"), + new URL ((String)elem.getAttribute ("url")), + elem.getAttribute ("type"))); + } catch (MalformedURLException e2) { + if (debug) + System.err.println ("Bad URL: " + elem.getAttribute ("url")); + } + } + + MobyResourceRef[] results = new MobyResourceRef [v.size()]; + v.copyInto (results); + + // Add this data to the cache in case we get called again + setContents (cacheId, results); + + return results; + } + + /************************************************************************** + * + *************************************************************************/ + public InputStream getResource (String resourceName) + throws MobyException { + + MobyResourceRef[] resourceRefs = getResourceRefs(); + for (int i = 0; i < resourceRefs.length; i++) { + if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { + return Utils.getInputStream (resourceRefs[i].getResourceLocation()); + } + } + throw new MobyException ("No resource found for '" + resourceName + "'."); + } + + /************************************************************************** + * Return a case-insensitive comparator of Strings. It is used to + * create various TreeMaps where keys are strings. + *************************************************************************/ + protected static Comparator getStringComparator() { + return new Comparator() { + public int compare (Object o1, Object o2) { + return ((String)o1).compareToIgnoreCase ((String)o2); + } + }; + } + + // cache URL/URI so we only check once + private static String CHECKED_URL = null; + private static String CHECKED_URI = null; + + /** + * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared + * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods + * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. + * + * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism + */ + public static CentralImpl getDefaultCentral() throws MobyException{ + return getDefaultCentral(null); + } + + public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ + if(reg == null && defaultCentrals.containsKey("")){ + return defaultCentrals.get(""); + } + else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ + return defaultCentrals.get(reg.getEndpoint()); + } + + String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); + if(resURL != null){ + System.err.println("Loading "+resURL); + try{ + LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); + for(String line = reader.readLine(); line != null; line = reader.readLine()){ + if(!line.trim().startsWith("#")){ + className = line.trim(); + break; + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Error reading " + resURL, + e); + } + } + try{ + System.err.println("Central class is "+className); + Class clazz = Class.forName(className); + if(reg == null){ // should use default nullary c-tor + defaultCentrals.put("", (CentralImpl) clazz.newInstance()); + } + else{ // should have (String endpoint, String namespace) c-tor + for(Constructor ctor: clazz.getDeclaredConstructors()){ + Class[] params = ctor.getParameterTypes(); + if(params.length == 2 && params[0].getName().equals("java.lang.String") && + params[1].getName().equals("java.lang.String") ){ + defaultCentrals.put(reg.getEndpoint(), + (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); + break; + } + } + if(!defaultCentrals.containsKey(reg.getEndpoint())){ + logger.log(Level.WARNING, + "Could not find required (String endpoint, String namespace)" + + "constructor for class " + className); + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Could not load class " + className, + e); + if(reg == null){ + defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. + } + else{ + defaultCentrals.put(reg.getEndpoint(), + new CentralImpl(reg.getEndpoint(), reg.getNamespace())); + } + } + + return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); + } + + /** + * + * @return a String representing the Default mobycentral endpoint. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central endpoint is returned, otherwise DEFAULT_ENDPOINT + * is returned. + */ + public static String getDefaultURL() { + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + + if (check) { + // return the last checked url if we have done this before + if (CHECKED_URL != null && CHECKED_URL.trim() != "") { + return CHECKED_URL; + } + + // create a HttpClient object + HttpClient client = new HttpClient(); + // set up the Head method + HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); + // do not follow redirects or we will get a 411 error + method.setFollowRedirects(false); + // retry 3 times + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); + // set the user agent ... should probably make this something more reasonable + method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); + try { + // Execute the method. + int statusCode = client.executeMethod(method); + + if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { + System.err.println("Method failed: " + + method.getStatusLine()); + } else { + try { + String location = method.getResponseHeader("location").getValue(); + CHECKED_URL = location; + try { + CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; + } catch (MalformedURLException murle ) { + CHECKED_URI = DEFAULT_NAMESPACE; + } + return CHECKED_URL; + } catch (NullPointerException npe) { + return DEFAULT_ENDPOINT; + } + } + } catch (HttpException e) { + System.err.println("Fatal protocol violation: " + + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + System.err.println("Fatal transport error: " + e.getMessage()); + e.printStackTrace(); + } finally { + // Release the connection. + method.releaseConnection(); + } + + } else { + return DEFAULT_ENDPOINT; + } + return DEFAULT_ENDPOINT; + } + + /** + * + * @return a String representing the default mobycentral uri. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central namespace is returned, otherwise DEFAULT_NAMESPACE + * is returned. + */ + public static String getDefaultURI() { + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + if (check) { + if (CHECKED_URI != null && CHECKED_URI.trim() != "") { + return CHECKED_URI; + } + // need to check ... + getDefaultURL(); + return CHECKED_URI; + } else { + return DEFAULT_NAMESPACE; + } + } + /************************************************************************** + * Convert non-suitable characters in a XML string into their + * entity references.

      + * + * Adapted from jDom. + * + * @param str input to be converted + * @return If there were any non-suitable characters, return a new + * string with those characters escaped, otherwise return the + * unmodified input string + * + *************************************************************************/ + public String escapeXML (String str) { + StringBuffer buffer = null; + char ch; + String entity; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt (i); + switch (ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; + case '&' : + entity = "&"; + break; + default : + entity = null; + break; + } + if (buffer == null) { + if (entity != null) { + // An entity occurred, so we'll have to use StringBuffer + // (allocate room for it plus a few more entities). + buffer = new StringBuffer (str.length() + 20); + // Copy previous skipped characters and fall through + // to pickup current character + buffer.append (str.substring (0, i)); + buffer.append (entity); + } + } else { + if (entity == null) { + buffer.append (ch); + } else { + buffer.append (entity); + } + } + } + + // If there were any entities, return the escaped characters + // that we put in the StringBuffer. Otherwise, just return + // the unmodified input string. + return (buffer == null) ? str : buffer.toString(); + } + + /************************************************************************* + * Format an exception. + *************************************************************************/ + public static String formatFault (AxisFault e, String endpoint, QName method) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + formatFault (e, new PrintStream (baos), endpoint, method); + return baos.toString(); + } + + /************************************************************************* + * Format an exception. + *************************************************************************/ + public static void formatFault (AxisFault e, PrintStream out, + String endpoint, QName method) { + + out.println ("===ERROR==="); + out.println ("Fault details:"); + // for some obvious errors I do not print all details (with a lenghty trace stack) + String faultString = e.getFaultString(); + if ( (! faultString.startsWith ("java.net.ConnectException")) && + (faultString.indexOf ("Could not find class for the service named:") == -1) + ) { + org.w3c.dom.Element[] details = e.getFaultDetails(); + for (int i = 0; i < details.length; i++) { + String s = details[i].toString().replaceAll ("<", "<"); + s = s.replaceAll (">", ">"); + out.println (s); + } + } + out.println ("Fault string: " + faultString); + out.println ("Fault code: " + e.getFaultCode()); + out.println ("Fault actor: " + e.getFaultActor()); + if (endpoint != null || method != null) + out.println ("When calling:"); + if (endpoint != null) + out.println ("\t" + endpoint); + if (method != null) + out.println ("\t" + method); + out.println ("==========="); + } + + +} From groscurt at dev.open-bio.org Wed Dec 3 15:21:13 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 10:21:13 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031521.mB3FLDqF013719@dev.open-bio.org> groscurt Wed Dec 3 10:21:13 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard In directory dev.open-bio.org:/tmp/cvs-serv13676/src/main/org/biomoby/service/dashboard Modified Files: SimpleClientPanel.java ServiceCallerModel.java DashboardProperties.java Log Message: changes made for the authentication... without formatting this time moby-live/Java/src/main/org/biomoby/service/dashboard SimpleClientPanel.java,1.13,1.14 ServiceCallerModel.java,1.7,1.8 DashboardProperties.java,1.30,1.31 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java 2008/11/26 08:54:21 1.13 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/SimpleClientPanel.java 2008/12/03 15:21:12 1.14 @@ -1,791 +1,838 @@ -// SimpleClientPanel.java -// -// Created: December 2005 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.service.dashboard; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.util.Date; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.ButtonGroup; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JPasswordField; -import javax.swing.JRadioButton; -import javax.swing.JSplitPane; -import javax.swing.JTextField; -import javax.swing.tree.DefaultMutableTreeNode; - -import org.biomoby.service.dashboard.data.DataContainer; -import org.biomoby.service.dashboard.data.ServiceInputPanel; -import org.biomoby.shared.MobyDataType; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.tulsoft.shared.UUtils; -import org.tulsoft.tools.gui.AwtUtils; -import org.tulsoft.tools.gui.JFileChooserWithHistory; -import org.tulsoft.tools.gui.JTextFieldWithHistory; -import org.tulsoft.tools.gui.SwingUtils; - -/** - * A panel allowing to formulate input data and to call an arbitrary Biomoby service. Its interface is however not that - * user-friendly, and it is supposed to be used more or less for testing purposes in time when a new service is being - * created and developed. - *

      - * - * @author Martin Senger - * @version $Id$ - */ - -public class SimpleClientPanel extends AbstractPanel { - - private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory - .getLog( SimpleClientPanel.class ); - - /** - * A property name. Its value contains a name of color that will be used to display service name. - */ - protected static final String P_S_TITLE_COLOR = "simpleclient.service.title.color"; - - /** - * A property name. Its value contains a name of color that will be used as background for editable console with XML - * input. - */ - protected static final String P_S_EDIT_BGCOLOR = "simpleclient.service.edit.bgcolor"; - - // some texts - protected static final String INIT_SELECT = "

      Start by selecting a service
      " - + "that you wish to call.
      "; - - protected static final String CALLER_ERROR = "Sorry, an error happened when calling a service.\n\n"; - - protected static final Insets BREATH_UP = new Insets( 6, 6, 0, 6 ); - protected static final Insets BREATH_DOWN = new Insets( 0, 6, 6, 6 ); - - // associated models working behind the scene - RegistryModel registryModel; - ServiceCallerModel callerModel; - - // components that are used from more methods - JLabel selService; - CommonConsole input; - JFileChooserWithHistory outFile, inFile; - JButton runButton, stopButton; - JCheckBox iShowXML, iFromFile; - JTextFieldWithHistory className, endpoint; - JPanel dataTablesPanel; - ServiceInputPanel inputDataTables; - MySwingWorker runWorker; - ResultsPanel results; - JComponent resultsComp; - JSplitPane resSplit; - // JTextFieldWithHistory recentServices; - - boolean selectionAllowed = false; - - // shared icons - protected static Icon runIcon, runIconDis; - protected static Icon stopIcon, stopIconDis; - protected static Icon addDataIcon, addDataIconDis; - - /******************************************************************************************************************* - * Default constructor. - ******************************************************************************************************************/ - public SimpleClientPanel() { - super(); - panelIconFileName = "images/debug.gif"; - } - - /******************************************************************************************************************* - * Load shared icons. - ******************************************************************************************************************/ - protected void loadIcons() { - super.loadIcons(); - - if ( runIcon == null ) runIcon = loadIcon( "images/smallRun.gif" ); - if ( runIconDis == null ) runIconDis = loadIcon( "images/smallRun_dis.gif" ); - - if ( stopIcon == null ) stopIcon = loadIcon( "images/smallCancel.gif" ); - if ( stopIconDis == null ) stopIconDis = loadIcon( "images/smallCancel_dis.gif" ); - - if ( addDataIcon == null ) addDataIcon = loadIcon( "images/smallAnnotate.gif" ); - if ( addDataIconDis == null ) addDataIconDis = loadIcon( "images/smallAnnonate_dis.gif" ); - - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public JComponent getComponent( PropertyChannel aPropertyChannel ) { - setPropertyChannel( aPropertyChannel ); - registryModel = createRegistryModel(); - callerModel = new ServiceCallerModel(); - callerModel.setPropertyChannel( aPropertyChannel ); - - if ( pComponent != null ) return pComponent; - pComponent = new JPanel( new GridBagLayout(), true ); - - // result panel - results = new ResultsPanel(); - resultsComp = results.getComponent( aPropertyChannel ); - propertyChannel.addPropertyChangeListener( new PropertyChangeListener() { - public void propertyChange( PropertyChangeEvent e ) { - if ( DP_DETACH_VIEW.equals( e.getPropertyName() ) ) { - - MobyService srv = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - String title = ( srv == null ? "Service results" : srv.getName() + " at " + new Date() ); - JComponent current = results.getComponent( propertyChannel ); - results.adjustForDetachement(); - JFrame newFrame = SwingUtils.createSoftMainFrame( current, title ); - Dimension dim = current.getPreferredSize(); - SwingUtils.showMainFrameRelativeTo( pComponent, newFrame, ( int ) dim.getWidth(), ( int ) dim - .getHeight() ); - results = new ResultsPanel(); - resultsComp = results.getComponent( propertyChannel ); - resSplit.setBottomComponent( resultsComp ); - } - } - } ); - - // panel with all the fields (except for building inputs) - JPanel controls = getControlPanel(); - - // panel with input data - JPanel inputData = getInputPanel(); - updateInputDataPanel( INIT_SELECT ); - - // service ontology tree - JPanel sBoard = new JPanel( new GridBagLayout() ); - // JLabel lRecent = new JLabel ("Recently called services"); - // recentServices = createText (null, - // DP_SC_SERVICES, - // DP_SC_SERVICES); - // recentServices.addActionListener (new ActionListener() { - // public void actionPerformed (ActionEvent e) { - // String contents = ((JTextFieldWithHistory)e.getSource()).getText(); - // if (! "".equals (contents) && selectionAllowed) { - // System.out.println ("SEL: " + contents); - // selectService (contents); - // } - // } - // }); - - ServicesBoard servicesBoard = new ServicesBoard( registryModel, null, propertyChannel, new CustomServicesTree( - registryModel, null ) ); - log.debug( "Services tree update started" ); - servicesBoard.updateTree( CommonTree.SORTED_BY_AUTHORITY ); - // SwingUtils.addComponent (sBoard, lRecent, 0, 0, 1, 1, NONE, NWEST, 0.0, 0.0, BREATH_UP); - // SwingUtils.addComponent (sBoard, recentServices, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0, BREATH_DOWN); - SwingUtils.addComponent( sBoard, servicesBoard, 0, 2, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - - // split it into moving panels - JSplitPane split = hSplit( resSplit = vSplit( hSplit( controls, sBoard, 0.5 ), resultsComp, 0.1 ), inputData, - 0.5 ); - - SwingUtils.addComponent( pComponent, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - - // initialize by a last used service name from preferences - String lastServiceName = getPrefValue( DP_SC_SERVICE_NAME, "" ); - if ( !"".equals( lastServiceName ) ) selectService( lastServiceName ); - - return pComponent; - } - - /******************************************************************************************************************* - * Create a sub-panel for all the controls... - ******************************************************************************************************************/ - protected JPanel getControlPanel() { - JPanel p = new JPanel( new GridBagLayout() ); - - // (selected) service name - selService = new JLabel(); - selService.setFont( FAT_BORDER_FONT ); - selService.setForeground( GraphColours.getColour( DashboardConfig.getString( P_S_TITLE_COLOR, null ), - Color.blue ) ); - - // how to invoke the service - JPanel howTo = createTitledPanel( "Service invocation" ); - endpoint = createText( null, DP_ENDPOINT, DP_ENDPOINT ); - className = createText( null, DP_IMPL_CLASS, DP_IMPL_CLASS ); - - ButtonGroup group = new ButtonGroup(); - JRadioButton htNone, htRegistry, htEndpoint, htLocal, htNewURL; - group.add( htEndpoint = createHowToButton( "Use service's usual endpoint", DP_CS_URL ) ); - htNone = createHowToButton( "No real call, just show/echo input", DP_CS_NONE ); - htNone.addItemListener( new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - if ( enabled ) - runButton.setText( " Show Input " ); - else { - if ( propertyChannel.getBoolean( DP_INP_PING, false ) ) { - runButton.setText( " Ping Service " ); - } - else { - runButton.setText( " Call Service " ); - } - } - } - } ); - group.add( htNone ); - group.add( htRegistry = createHowToButton( "Ask registry where service is, and call it", DP_CS_REGISTRY ) ); - group.add( htNewURL = createHowToButton( "Use this endpoint", DP_CS_NEWURL ) ); - group.add( htLocal = createHowToButton( "Use this local class", DP_CS_CLASS ) ); - - // run the service - // determine button text from preferences - boolean usingPing = getPrefValue( DP_INP_PING, false ); - boolean usingAsBytes = getPrefValue( DP_INP_ASBYTES, false ); - String runLabel = " Call Service "; - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runLabel = " Show Input "; - else if ( usingPing ) runLabel = " Ping Service "; - - runButton = createButton( runLabel, "Invoke selected service", KeyEvent.VK_C, new ActionListener() { - public void actionPerformed( ActionEvent e ) { - MobyService srv = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - if ( srv != null ) { - // if the authentication was selected a dialog opens to ask for the user/password - if ( propertyChannel.getBoolean( DP_AUTHENTICATION, false ) ) { - askForAuthentication(); - } - // if not make sure to remove any previous authentication - else { - propertyChannel.remove( DP_USER_AUTHENTICATION ); - propertyChannel.remove( DP_PASSWORD_AUTHENTICATION ); - } - runWorker = new MySwingWorker( srv ); - runWorker.start(); - } - } - } ); - runButton.setIcon( runIcon ); - runButton.setDisabledIcon( runIconDis ); - runButton.setEnabled( false ); // will enable when a service is selected - - stopButton = createButton( " Stop service ", "Cancel connection to a running service", KeyEvent.VK_S, - new ActionListener() { - public void actionPerformed( ActionEvent e ) { - if ( runWorker != null ) { - // runWorker.interrupt(); // no sense with the current Biomoby API - runWorker.cancel(); - } - serviceFinished(); - } - } ); - stopButton.setIcon( stopIcon ); - stopButton.setDisabledIcon( stopIconDis ); - stopButton.setEnabled( false ); // will enable when a service is called - - JPanel buttonPanel = createButtonPanel( new JButton[] { runButton, stopButton } ); - - JCheckBox asPing = createCheckBox( "'Ping' this service", usingPing, -1, new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPropertySelect( enabled, DP_INP_PING ); - setPrefValue( DP_INP_PING, enabled ); - propertyChannel.put( DP_INP_PING, new Boolean( enabled ).toString() ); - if ( enabled ) { - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runButton.setText( " Show Input " ); - else - runButton.setText( " Ping Service " ); - } - else { - if ( propertyChannel.getString( DP_CALL_SERVICE ).equals( DP_CS_NONE ) ) - runButton.setText( " Show Input " ); - else - runButton.setText( " Call Service " ); - } - } - } ); - setPropertySelect( usingPing, DP_INP_PING ); - asPing.setToolTipText( "A Moby 'Ping' is used to determine if the service is responsive " - + "and if it responds in an API-compliant manner." ); - Font font = asPing.getFont(); - asPing.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - JCheckBox asBytes = createCheckBox( "Send data to service as a byte array", usingAsBytes, -1, - new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPropertySelect( enabled, DP_INP_ASBYTES ); - setPrefValue( DP_INP_ASBYTES, enabled ); - propertyChannel.put( DP_INP_ASBYTES, new Boolean( enabled ).toString() ); - } - } ); - setPropertySelect( usingAsBytes, DP_INP_ASBYTES ); - asBytes.setToolTipText( "It should not have any effect on result; it is for debugging" ); - font = asBytes.getFont(); - asBytes.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - JCheckBox authenticationBox = createCheckBox( "Use a user/password for authentication", false, -1, - new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - propertyChannel.put( DP_AUTHENTICATION, e.getStateChange() == ItemEvent.SELECTED ); - } - } ); - authenticationBox.setToolTipText( "If the service requires authentication. " - + "A dialog will open if you call the service to enter the authentication." ); - font = authenticationBox.getFont(); - authenticationBox.setFont( font.deriveFont( Math.max( 1, font.getSize2D() - 1 ) ) ); - - SwingUtils.addComponent( howTo, htEndpoint, 0, 0, 2, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htNewURL, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, endpoint, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htRegistry, 0, 2, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, htLocal, 0, 3, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, className, 1, 3, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( howTo, htNone, 0, 4, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, asPing, 0, 5, 2, 1, NONE, NWEST, 0.0, 0.0, BREATH_TOP ); - SwingUtils.addComponent( howTo, asBytes, 0, 6, 2, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( howTo, authenticationBox, 0, 7, 2, 1, NONE, NWEST, 0.0, 0.0 ); - - Component glue = Box.createVerticalGlue(); - SwingUtils.addComponent( p, selService, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0 ); - SwingUtils.addComponent( p, howTo, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( p, buttonPanel, 0, 2, 1, 1, NONE, CENTER, 0.0, 0.0, BREATH_TOP ); - SwingUtils.addComponent( p, glue, 0, 3, 1, 1, VERT, NWEST, 0.0, 1.0 ); - return p; - } - - /******************************************************************************************************************* - * Select/unselect using 'send as bytes' or 'ping'... - ******************************************************************************************************************/ - protected void setPropertySelect( boolean enabled, String property ) { - setPrefValue( property, enabled ); - propertyChannel.put( property, new Boolean( enabled ).toString() ); - } - - /******************************************************************************************************************* - * Opens a dialog and asks for webservice authentication - ******************************************************************************************************************/ - private void askForAuthentication() { - final JDialog dialog = new JDialog( new JFrame(), "Authentication", true ); - JPanel panel = new JPanel( new GridBagLayout() ); - panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); - - Insets insets = new Insets( 4, 4, 4, 4 ); - - JLabel label = new JLabel( "Please enter your username and password !" ); - SwingUtils.addComponent( panel, label, 0, 0, 2, 1, HORI, CENTER, 1, 0, insets ); - - label = new JLabel( "User: " ); - SwingUtils.addComponent( panel, label, 0, 1, 1, 1, HORI, NWEST, 0, 0, insets ); - - final JTextField userField = new JTextField( propertyChannel.getString( DP_USER_AUTHENTICATION ), 20 ); - SwingUtils.addComponent( panel, userField, 1, 1, 1, 1, HORI, NWEST, 0, 0, insets ); - - label = new JLabel( "Password: " ); - SwingUtils.addComponent( panel, label, 0, 2, 1, 1, HORI, NWEST, 0, 0, insets ); - - final JPasswordField passwordField = new JPasswordField( - propertyChannel.getString( DP_PASSWORD_AUTHENTICATION ), 20 ); - SwingUtils.addComponent( panel, passwordField, 1, 2, 1, 1, HORI, NWEST, 0, 0, insets ); - - JButton button = new JButton( "Enter..." ); - button.addActionListener( new ActionListener() { - public void actionPerformed( ActionEvent e ) { - propertyChannel.put( DP_USER_AUTHENTICATION, userField.getText() ); - propertyChannel.put( DP_PASSWORD_AUTHENTICATION, passwordField.getPassword() ); - - dialog.setVisible( false ); - } - } ); - SwingUtils.addComponent( panel, button, 0, 3, 2, 1, HORI, CENTER, 0, 0, insets ); - - dialog.setContentPane( panel ); - dialog.pack(); - dialog.setLocationRelativeTo( this ); - dialog.setVisible( true ); - } - - /******************************************************************************************************************* - * Create a specialized radio button - for various ways how to call a service. - ******************************************************************************************************************/ - private JRadioButton createHowToButton( String title, String howTo ) { - JRadioButton radio = new JRadioButton( title ); - radio.setActionCommand( howTo ); - radio.addActionListener( howToListener ); - String initHowTo = getPrefValue( DP_CALL_SERVICE, DP_CS_NONE ); - if ( howTo.equals( initHowTo ) ) { - radio.setSelected( true ); - radio.setEnabled( true ); - propertyChannel.put( DP_CALL_SERVICE, howTo ); - } - endpoint.setEnabled( initHowTo.equals( DP_CS_NEWURL ) ); - className.setEnabled( initHowTo.equals( DP_CS_CLASS ) ); - return radio; - } - - // - private ActionListener howToListener = new ActionListener() { - public void actionPerformed( ActionEvent e ) { - String howTo = e.getActionCommand(); - setPrefValue( DP_CALL_SERVICE, howTo ); - propertyChannel.put( DP_CALL_SERVICE, howTo ); - endpoint.setEnabled( howTo.equals( DP_CS_NEWURL ) ); - className.setEnabled( howTo.equals( DP_CS_CLASS ) ); - } - }; - - /******************************************************************************************************************* - * Create a specialized check box for "what to do with input/output"... - ******************************************************************************************************************/ - private JCheckBox createDataBox( String title, final String preferenceKey, boolean defaultValue ) { - boolean initValue = getPrefValue( preferenceKey, defaultValue ); - propertyChannel.put( preferenceKey, new Boolean( initValue ).toString() ); - return createCheckBox( title, initValue, -1, new ItemListener() { - public void itemStateChanged( ItemEvent e ) { - boolean enabled = ( e.getStateChange() == ItemEvent.SELECTED ); - setPrefValue( preferenceKey, enabled ); - propertyChannel.put( preferenceKey, new Boolean( enabled ).toString() ); - inFile.setEnabled( iFromFile.isSelected() ); - } - } ); - } - - /******************************************************************************************************************* - * Create a sub-panel for service inputs... - ******************************************************************************************************************/ - protected JPanel getInputPanel() { - JPanel inputData = new JPanel( new GridBagLayout() ); - inputData - .setBorder( createFatBorder( "Service Input Data", GraphColours.getColour( "cadetblue", Color.blue ) ) ); - - // upper part (tables, input file, show-xml check-box) - JPanel upper = new JPanel( new GridBagLayout() ); - - dataTablesPanel = new JPanel( new GridBagLayout() ); - - iFromFile = createDataBox( "Take an input from this XML file", DP_SC_IN_FILE, false ); - inFile = createFileSelector( "Select input XML for calling a service", "Select", null, DP_SC_INPUT_FILE, - DP_SC_INPUT_FILE ); - inFile.setEnabled( iFromFile.isSelected() ); - - iShowXML = createDataBox( "Show input as XML", DP_INP_SHOWXML, true ); - - SwingUtils.addComponent( upper, dataTablesPanel, 0, 0, 2, 1, BOTH, NWEST, 1.0, 1.0 ); - SwingUtils.addComponent( upper, iFromFile, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0 ); - SwingUtils.addComponent( upper, inFile, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0 ); - SwingUtils.addComponent( upper, iShowXML, 0, 2, 1, 1, NONE, NWEST, 0.0, 0.0 ); - - // lower part (console showing/editing input XML) - input = new EditableConsole(); - input.setAppendMode( false ); - input.setVerboseMode( false ); - - // split upper and lower parts into moving panels - JSplitPane split = vSplit( upper, input, 0.5 ); - SwingUtils.addComponent( inputData, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - return inputData; - } - - class EditableConsole extends CommonConsole { - - public EditableConsole() { - super(); - textArea.setEditable( true ); - textArea.setBackground( GraphColours.getColour( DashboardConfig.getString( P_S_EDIT_BGCOLOR, null ), - textArea.getBackground() ) ); - } - } - - /******************************************************************************************************************* - * Replace the global 'dataTablesPanel' with an information text. - ******************************************************************************************************************/ - protected void updateInputDataPanel( String info ) { - dataTablesPanel.removeAll(); - AwtUtils.redisplay( dataTablesPanel ); - - JLabel text = new JLabel( info ); - SwingUtils.addComponent( dataTablesPanel, text, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0 ); - dataTablesPanel.validate(); - return; - } - - /******************************************************************************************************************* - * Replace the global 'dataTablesPanel' with fields defining the input data for the given service. - ******************************************************************************************************************/ - protected void updateInputDataPanel( MobyService service, MobyDataType[] dataTypes ) { - dataTablesPanel.removeAll(); - - inputDataTables = new ServiceInputPanel( service, dataTypes ); - SwingUtils.addComponent( dataTablesPanel, inputDataTables, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0 ); - dataTablesPanel.validate(); - } - - /******************************************************************************************************************* - * Find 'dataTypeToBeFound in 'dataTypes' and return it. The same could be achieved by calling - * registryModel.getDataType() but here I do not want to create yet another swing worker for it. - ******************************************************************************************************************/ - protected MobyDataType findDataType( String dataTypeToBeFound, MobyDataType[] dataTypes ) { - for ( int i = 0; i < dataTypes.length; i++ ) { - if ( dataTypeToBeFound.equals( dataTypes[ i ].getName() ) ) return dataTypes[ i ]; - } - log.error( "Strange, data type '" + dataTypeToBeFound + "' was not found in " + dataTypes.length - + " data types." ); - return null; - } - - /******************************************************************************************************************* - * - * A worker that calls the service... - * - ******************************************************************************************************************/ - class MySwingWorker extends SwingWorker { - - MobyException exception = null; - DataContainer data = new DataContainer(); - boolean wasCancelled = false; - MobyService service; - - public MySwingWorker( MobyService service ) { - super(); - this.service = service; - data.setMetadata( propertyChannel ); - } - - public void cancel() { - wasCancelled = true; - propertyChannel.fire( DP_STATUS_MSG, "Service invocation cancelled." ); - } - - public Object construct() { - try { - runButton.setEnabled( false ); - propertyChannel.fire( DP_STATUS_MSG, "Calling service " + service.getName() + "..." ); - - // create a data container with input data... - if ( propertyChannel.getBoolean( DP_SC_IN_FILE, false ) ) { - - // ...either from a file - String inputFile = propertyChannel.getString( DP_SC_INPUT_FILE ); - if ( UUtils.isEmpty( inputFile ) ) throw new MobyException( "No input XML file given." ); - data.setDataFromFile( new File( inputFile ) ); - - } - else { - data.setData( inputDataTables.toXML() ); - } - - // optionally, show XML data: we want to show this XML - // input only (a) if it was explicitly asked for (property - // DP_INP_SHOWXML is true), or (b) if "no real service - // call" was selected (property DP_CALL_SERVICE has value - // DP_CS_NONE) - if ( DP_CS_NONE.equals( propertyChannel.getString( DP_CALL_SERVICE ) ) - || ( propertyChannel.getBoolean( DP_INP_SHOWXML, false ) ) ) { - input.setText( ( String ) data.getData() ); - } - - // If we are only pinging the service, set the data object to an empty message - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - String emptyMsg = "\n" - + "\n" + " \n" - + ""; - data.setData( emptyMsg ); - input.setText( emptyMsg ); - } - - // finally, call the service - stopButton.setEnabled( true ); - callerModel.runIt( data ); - - } - catch ( MobyException e ) { - exception = e; - - } - catch ( Error e ) { - exception = new MobyException( e.toString() ); - } - return null; // not used here - } - - // runs on the event-dispatching thread - public void finished() { - if ( wasCancelled ) { - // service was interrupted by the Stop button - do - // nothing (the whole GUI should be already in a good - // state - the button 'Stop' took care about it) - return; - } - - if ( exception == null ) { - - // handle results here (using renderers...) - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - propertyChannel.fire( DP_STATUS_MSG, service.getName() + " isAlive." ); - } - else { - propertyChannel.fire( DP_STATUS_MSG, "Service invocation finished." ); - } - - if ( !DP_CS_NONE.equals( propertyChannel.getString( DP_CALL_SERVICE ) ) ) { - results.updateComponent( data ); - } - - } - else { - if ( propertyChannel.getString( DP_INP_PING ).toLowerCase().equals( "true" ) ) { - propertyChannel.fire( DP_STATUS_MSG, service.getName() + " is dead." ); - results.removeResults(); - } - else { - propertyChannel.fire( DP_STATUS_MSG, "Service invocation failed." ); - error( CALLER_ERROR, exception ); - } - exception.printStackTrace(); - } - serviceFinished(); - } - } - - /******************************************************************************************************************* - * Called when a call to a service finished. - ******************************************************************************************************************/ - protected void serviceFinished() { - runButton.setEnabled( true ); - stopButton.setEnabled( false ); - } - - /******************************************************************************************************************* - * Called when a service is selected in a service tree (or in a 'recently used services' combo box), and also at the - * beginning when a service name is retrieved from user preferences. - * - * Get selected service from a registry model and generate a new 'input data panel' to reflect input data of the - * selected service. - ******************************************************************************************************************/ - protected void selectService( final String serviceName ) { - final Object source = this; - final SwingWorker worker = new SwingWorker() { - MobyService service; - MobyDataType[] dataTypes; - - public Object construct() { - try { - service = registryModel.getService( serviceName ); - dataTypes = registryModel.getDataTypes( source ); - } - catch ( MobyException e ) { - error( ServicesTree.SERVICES_ACCESS_ERROR, e ); - } - return service; // not used here - } - - // runs on the event-dispatching thread. - public void finished() { - if ( service == null ) { - deselectService(); - } - else { - updateInputDataPanel( service, dataTypes ); - selService.setText( service.getName() ); - // selectionAllowed = false; - // recentServices.setText (service.getName()); - // selectionAllowed = true; - propertyChannel.put( DP_SC_SERVICE, service ); - runButton.setEnabled( true ); - - } - } - }; - worker.start(); - } - - /******************************************************************************************************************* - * Called when no service is selected in order to display this fact on various places in the panel. - ******************************************************************************************************************/ - protected void deselectService() { - selService.setText( "" ); - updateInputDataPanel( INIT_SELECT ); - propertyChannel.remove( DP_SC_SERVICE ); - runButton.setEnabled( false ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getName() { - return "Simple Client"; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getDescription() { - return "A panel allowing to create input data and to call an arbitrary Biomoby service. " - + "Its purpose is mostly for the service developers to test their new services."; - } - - /******************************************************************************************************************* - * - * Customized tree of services... - * - ******************************************************************************************************************/ - protected class CustomServicesTree extends ServicesTree { - - /*************************************************************************************************************** - * Construtor - **************************************************************************************************************/ - public CustomServicesTree( RegistryModel model, CommonConsole console ) { - super( model, console ); - } - - /*************************************************************************************************************** - * - **************************************************************************************************************/ - protected void createPopups( String title ) { - super.createPopups( title ); - removeFromPopups( AC_RELOAD ); - removeSeparatorAfter( AC_COLLAPSE ); - } - - /*************************************************************************************************************** - * Service selected in a service tree... - **************************************************************************************************************/ - protected void selected( DefaultMutableTreeNode node ) { - if ( node == null ) { - // nothing selected - deselectService(); - return; - } - updateInputDataPanel( "Loading..." ); - selService.setText( "" ); - final CommonNode nodeObject = ( CommonNode ) node.getUserObject(); - String currentServiceName = nodeObject.getValue(); - selectService( currentServiceName ); - setPrefValue( DP_SC_SERVICE_NAME, currentServiceName ); - } - } - -} +// SimpleClientPanel.java +// +// Created: December 2005 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.service.dashboard; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.Date; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.ButtonGroup; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JRadioButton; +import javax.swing.JSplitPane; +import javax.swing.JTextField; +import javax.swing.tree.DefaultMutableTreeNode; + +import org.biomoby.service.dashboard.data.DataContainer; +import org.biomoby.service.dashboard.data.ServiceInputPanel; +import org.biomoby.shared.MobyDataType; +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.tulsoft.shared.UUtils; +import org.tulsoft.tools.gui.AwtUtils; +import org.tulsoft.tools.gui.JFileChooserWithHistory; +import org.tulsoft.tools.gui.JTextFieldWithHistory; +import org.tulsoft.tools.gui.SwingUtils; + +/** + * A panel allowing to formulate input data and to call an arbitrary + * Biomoby service. Its interface is however not that user-friendly, + * and it is supposed to be used more or less for testing purposes in + * time when a new service is being created and developed.

      + * + * @author Martin Senger + * @version $Id$ + */ + +public class SimpleClientPanel + extends AbstractPanel { + + private static org.apache.commons.logging.Log log = + org.apache.commons.logging.LogFactory.getLog (SimpleClientPanel.class); + + /** A property name. Its value contains a name of color that will + * be used to display service name. + */ + protected static final String P_S_TITLE_COLOR = "simpleclient.service.title.color"; + + /** A property name. Its value contains a name of color that will + * be used as background for editable console with XML input. + */ + protected static final String P_S_EDIT_BGCOLOR = "simpleclient.service.edit.bgcolor"; + + // some texts + protected static final String INIT_SELECT = + "

      Start by selecting a service
      " + + "that you wish to call.
      "; + + protected static final String CALLER_ERROR = + "Sorry, an error happened when calling a service.\n\n"; + + protected static final Insets BREATH_UP = new Insets (6,6,0,6); + protected static final Insets BREATH_DOWN = new Insets (0,6,6,6); + + // associated models working behind the scene + RegistryModel registryModel; + ServiceCallerModel callerModel; + + // components that are used from more methods + JLabel selService; + CommonConsole input; + JFileChooserWithHistory outFile, inFile; + JButton runButton, stopButton; + JCheckBox iShowXML, iFromFile; + JTextFieldWithHistory className, endpoint; + JPanel dataTablesPanel; + ServiceInputPanel inputDataTables; + MySwingWorker runWorker; + ResultsPanel results; + JComponent resultsComp; + JSplitPane resSplit; +// JTextFieldWithHistory recentServices; + + boolean selectionAllowed = false; + + // shared icons + protected static Icon runIcon, runIconDis; + protected static Icon stopIcon, stopIconDis; + protected static Icon addDataIcon, addDataIconDis; + + /********************************************************************* + * Default constructor. + ********************************************************************/ + public SimpleClientPanel() { + super(); + panelIconFileName = "images/debug.gif"; + } + + /********************************************************************* + * Load shared icons. + ********************************************************************/ + protected void loadIcons() { + super.loadIcons(); + + if (runIcon == null) runIcon = loadIcon ("images/smallRun.gif"); + if (runIconDis == null) runIconDis = loadIcon ("images/smallRun_dis.gif"); + + if (stopIcon == null) stopIcon = loadIcon ("images/smallCancel.gif"); + if (stopIconDis == null) stopIconDis = loadIcon ("images/smallCancel_dis.gif"); + + if (addDataIcon == null) addDataIcon = loadIcon ("images/smallAnnotate.gif"); + if (addDataIconDis == null) addDataIconDis = loadIcon ("images/smallAnnonate_dis.gif"); + + } + + /************************************************************************** + * + **************************************************************************/ + public JComponent getComponent (PropertyChannel aPropertyChannel) { + setPropertyChannel (aPropertyChannel); + registryModel = createRegistryModel(); + callerModel = new ServiceCallerModel(); + callerModel.setPropertyChannel (aPropertyChannel); + + if (pComponent != null) return pComponent; + pComponent = new JPanel (new GridBagLayout(), true); + + // result panel + results = new ResultsPanel(); + resultsComp = results.getComponent (aPropertyChannel); + propertyChannel.addPropertyChangeListener (new PropertyChangeListener() { + public void propertyChange (PropertyChangeEvent e) { + if (DP_DETACH_VIEW.equals (e.getPropertyName())) { + + MobyService srv = + (MobyService)propertyChannel.get (DP_SC_SERVICE); + String title = (srv == null ? "Service results" : + srv.getName() + " at " + new Date()); + JComponent current = results.getComponent (propertyChannel); + results.adjustForDetachement(); + JFrame newFrame = + SwingUtils.createSoftMainFrame (current, + title); + Dimension dim = current.getPreferredSize(); + SwingUtils.showMainFrameRelativeTo + (pComponent, newFrame, (int)dim.getWidth(), (int)dim.getHeight()); + results = new ResultsPanel(); + resultsComp = results.getComponent (propertyChannel); + resSplit.setBottomComponent (resultsComp); + } + }}); + + + // panel with all the fields (except for building inputs) + JPanel controls = getControlPanel(); + + // panel with input data + JPanel inputData = getInputPanel(); + updateInputDataPanel (INIT_SELECT); + + // service ontology tree + JPanel sBoard = new JPanel (new GridBagLayout()); +// JLabel lRecent = new JLabel ("Recently called services"); +// recentServices = createText (null, +// DP_SC_SERVICES, +// DP_SC_SERVICES); +// recentServices.addActionListener (new ActionListener() { +// public void actionPerformed (ActionEvent e) { +// String contents = ((JTextFieldWithHistory)e.getSource()).getText(); +// if (! "".equals (contents) && selectionAllowed) { +// System.out.println ("SEL: " + contents); +// selectService (contents); +// } +// } +// }); + + ServicesBoard servicesBoard = + new ServicesBoard (registryModel, + null, + propertyChannel, + new CustomServicesTree (registryModel, + null)); + log.debug ("Services tree update started"); + servicesBoard.updateTree (CommonTree.SORTED_BY_AUTHORITY); +// SwingUtils.addComponent (sBoard, lRecent, 0, 0, 1, 1, NONE, NWEST, 0.0, 0.0, BREATH_UP); +// SwingUtils.addComponent (sBoard, recentServices, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0, BREATH_DOWN); + SwingUtils.addComponent (sBoard, servicesBoard, 0, 2, 1, 1, BOTH, NWEST, 1.0, 1.0); + + // split it into moving panels + JSplitPane split = hSplit (resSplit = vSplit (hSplit (controls, + sBoard, 0.5), + resultsComp, 0.1), + inputData, + 0.5); + + SwingUtils.addComponent (pComponent, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + + // initialize by a last used service name from preferences + String lastServiceName = getPrefValue (DP_SC_SERVICE_NAME, ""); + if (! "".equals (lastServiceName)) + selectService (lastServiceName); + + return pComponent; + } + + /************************************************************************** + * Create a sub-panel for all the controls... + **************************************************************************/ + protected JPanel getControlPanel() { + JPanel p = new JPanel (new GridBagLayout()); + + // (selected) service name + selService = new JLabel(); + selService.setFont (FAT_BORDER_FONT); + selService.setForeground + (GraphColours.getColour (DashboardConfig.getString (P_S_TITLE_COLOR, null), + Color.blue)); + + // how to invoke the service + JPanel howTo = createTitledPanel ("Service invocation"); + endpoint = createText (null, DP_ENDPOINT, DP_ENDPOINT); + className = createText (null, DP_IMPL_CLASS, DP_IMPL_CLASS); + + ButtonGroup group = new ButtonGroup(); + JRadioButton htNone, htRegistry, htEndpoint, htLocal, htNewURL; + group.add (htEndpoint = createHowToButton ("Use service's usual endpoint", DP_CS_URL)); + htNone = createHowToButton ("No real call, just show/echo input", DP_CS_NONE); + htNone.addItemListener( + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + if (enabled) runButton.setText(" Show Input "); + else { + if (propertyChannel.getBoolean(DP_INP_PING, false)){ + runButton.setText(" Ping Service "); + } + else { + runButton.setText(" Call Service "); + } + } + } + }); + group.add (htNone); + group.add (htRegistry = createHowToButton ("Ask registry where service is, and call it", DP_CS_REGISTRY)); + group.add (htNewURL = createHowToButton ("Use this endpoint", DP_CS_NEWURL)); + group.add (htLocal = createHowToButton ("Use this local class", DP_CS_CLASS)); + + // run the service + // determine button text from preferences + boolean usingPing = getPrefValue (DP_INP_PING, false); + boolean usingAsBytes = getPrefValue (DP_INP_ASBYTES, false); + String runLabel = " Call Service "; + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runLabel = " Show Input "; + else if (usingPing) runLabel = " Ping Service "; + + runButton = + createButton (runLabel, + "Invoke selected service", + KeyEvent.VK_C, + new ActionListener() { + public void actionPerformed (ActionEvent e) { + MobyService srv = (MobyService)propertyChannel.get (DP_SC_SERVICE); + if (srv != null) { + // if the service requires authentication this is asked + if(propertyChannel.getBoolean(DP_AUTHENTICATION, false)) { + askForAuthentication(); + } + // remove possible remnants + else { + propertyChannel.remove(DP_USER_AUTHENTICATION); + propertyChannel.remove(DP_PASSWORD_AUTHENTICATION); + } + runWorker = new MySwingWorker (srv); + runWorker.start(); + } + } + }); + runButton.setIcon (runIcon); + runButton.setDisabledIcon (runIconDis); + runButton.setEnabled (false); // will enable when a service is selected + + stopButton = + createButton (" Stop service ", + "Cancel connection to a running service", + KeyEvent.VK_S, + new ActionListener() { + public void actionPerformed (ActionEvent e) { + if (runWorker != null) { +// runWorker.interrupt(); // no sense with the current Biomoby API + runWorker.cancel(); + } + serviceFinished(); + } + }); + stopButton.setIcon (stopIcon); + stopButton.setDisabledIcon (stopIconDis); + stopButton.setEnabled (false); // will enable when a service is called + + JPanel buttonPanel = createButtonPanel (new JButton[] { runButton, + stopButton }); + + JCheckBox asPing = createCheckBox + ("'Ping' this service", + usingPing, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPropertySelect (enabled, DP_INP_PING); + setPrefValue (DP_INP_PING, enabled); + propertyChannel.put (DP_INP_PING, + new Boolean (enabled).toString()); + if (enabled) { + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runButton.setText(" Show Input "); + else + runButton.setText(" Ping Service "); + } + else { + if (propertyChannel.getString(DP_CALL_SERVICE).equals(DP_CS_NONE)) + runButton.setText(" Show Input "); + else + runButton.setText(" Call Service "); + } + } + }); + setPropertySelect (usingPing, DP_INP_PING); + asPing.setToolTipText ("A Moby 'Ping' is used to determine if the service is responsive " + + "and if it responds in an API-compliant manner."); + Font font = asPing.getFont(); + asPing.setFont (font.deriveFont (Math.max (1, font.getSize2D() - 1))); + + JCheckBox asBytes = createCheckBox + ("Send data to service as a byte array", + usingAsBytes, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPropertySelect (enabled, DP_INP_ASBYTES); + setPrefValue (DP_INP_ASBYTES, enabled); + propertyChannel.put (DP_INP_ASBYTES, + new Boolean (enabled).toString()); + } + }); + setPropertySelect (usingAsBytes, DP_INP_ASBYTES); + asBytes.setToolTipText ("It should not have any effect on result; it is for debugging"); + font = asBytes.getFont(); + asBytes.setFont (font.deriveFont (Math.max (1, font.getSize2D() - 1))); + + JCheckBox authenticationBox = createCheckBox("Use a user/password for service authentication", false, -1, + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + propertyChannel.put(DP_AUTHENTICATION, e.getStateChange() == ItemEvent.SELECTED); + } + }); + authenticationBox.setToolTipText("If the service requires authentication." + + "A dialog will open if you call the service to enter the authentication."); + font = authenticationBox.getFont(); + authenticationBox.setFont(font.deriveFont(Math.max(1, font.getSize2D() -1))); + + SwingUtils.addComponent (howTo, htEndpoint, 0, 0, 2, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htNewURL, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, endpoint, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htRegistry, 0, 2, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, htLocal, 0, 3, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, className, 1, 3, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (howTo, htNone, 0, 4, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, asPing, 0, 5, 2, 1, NONE, NWEST, 0.0, 0.0, BREATH_TOP); + SwingUtils.addComponent (howTo, asBytes, 0, 6, 2, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (howTo, authenticationBox,0,7,2,1,NONE, NWEST, 0,0); + + Component glue = Box.createVerticalGlue(); + SwingUtils.addComponent (p, selService, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0); + SwingUtils.addComponent (p, howTo, 0, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (p, buttonPanel, 0, 2, 1, 1, NONE, CENTER, 0.0, 0.0, BREATH_TOP); + SwingUtils.addComponent (p, glue, 0, 3, 1, 1, VERT, NWEST, 0.0, 1.0); + return p; + } + + /** + * Opens a dialog to enter the authentication information + */ + private void askForAuthentication() { + final JDialog dialog = new JDialog( new JFrame(), "Authentication", true ); + JPanel panel = new JPanel( new GridBagLayout() ); + panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) ); + + Insets insets = new Insets( 4, 4, 4, 4 ); + + JLabel label = new JLabel( "Please enter your username and password !" ); + SwingUtils.addComponent( panel, label, 0, 0, 2, 1, HORI, CENTER, 1, 0, insets ); + + label = new JLabel( "User: " ); + SwingUtils.addComponent( panel, label, 0, 1, 1, 1, HORI, NWEST, 0, 0, insets ); + + final JTextField userField = new JTextField( propertyChannel.getString( DP_USER_AUTHENTICATION ), 20 ); + SwingUtils.addComponent( panel, userField, 1, 1, 1, 1, HORI, NWEST, 0, 0, insets ); + + label = new JLabel( "Password: " ); + SwingUtils.addComponent( panel, label, 0, 2, 1, 1, HORI, NWEST, 0, 0, insets ); + + final JPasswordField passwordField = new JPasswordField( + propertyChannel.getString( DP_PASSWORD_AUTHENTICATION ), 20 ); + SwingUtils.addComponent( panel, passwordField, 1, 2, 1, 1, HORI, NWEST, 0, 0, insets ); + + JButton button = new JButton( "Enter..." ); + button.addActionListener( new ActionListener() { + public void actionPerformed( ActionEvent e ) { + // sets the user and password in the propertychannel + propertyChannel.put( DP_USER_AUTHENTICATION, userField.getText() ); + propertyChannel.put( DP_PASSWORD_AUTHENTICATION, new String(passwordField.getPassword() )); + + dialog.setVisible( false ); + } + } ); + SwingUtils.addComponent( panel, button, 0, 3, 2, 1, HORI, CENTER, 0, 0, insets ); + + dialog.setContentPane( panel ); + dialog.pack(); + dialog.setLocationRelativeTo( this ); + dialog.setVisible( true ); + } + + /************************************************************************** + * Select/unselect using 'send as bytes' or 'ping'... + **************************************************************************/ + protected void setPropertySelect (boolean enabled, String property) { + setPrefValue (property, enabled); + propertyChannel.put (property, new Boolean (enabled).toString()); + } + + /************************************************************************** + * Create a specialized radio button - for various ways how to + * call a service. + **************************************************************************/ + private JRadioButton createHowToButton (String title, String howTo) { + JRadioButton radio = new JRadioButton (title); + radio.setActionCommand (howTo); + radio.addActionListener (howToListener); + String initHowTo = getPrefValue (DP_CALL_SERVICE, DP_CS_NONE); + if (howTo.equals (initHowTo)) { + radio.setSelected (true); + radio.setEnabled (true); + propertyChannel.put (DP_CALL_SERVICE, howTo); + } + endpoint.setEnabled (initHowTo.equals (DP_CS_NEWURL)); + className.setEnabled (initHowTo.equals (DP_CS_CLASS)); + return radio; + } + + // + private ActionListener howToListener = new ActionListener() { + public void actionPerformed (ActionEvent e) { + String howTo = e.getActionCommand(); + setPrefValue (DP_CALL_SERVICE, howTo); + propertyChannel.put (DP_CALL_SERVICE, howTo); + endpoint.setEnabled (howTo.equals (DP_CS_NEWURL)); + className.setEnabled (howTo.equals (DP_CS_CLASS)); + } + }; + + /************************************************************************** + * Create a specialized check box for "what to do with input/output"... + **************************************************************************/ + private JCheckBox createDataBox (String title, + final String preferenceKey, + boolean defaultValue) { + boolean initValue = getPrefValue (preferenceKey, defaultValue); + propertyChannel.put (preferenceKey, + new Boolean (initValue).toString()); + return createCheckBox + (title, initValue, -1, + new ItemListener() { + public void itemStateChanged (ItemEvent e) { + boolean enabled = (e.getStateChange() == ItemEvent.SELECTED); + setPrefValue (preferenceKey, enabled); + propertyChannel.put (preferenceKey, + new Boolean (enabled).toString()); + inFile.setEnabled (iFromFile.isSelected()); + } + }); + } + + /************************************************************************** + * Create a sub-panel for service inputs... + **************************************************************************/ + protected JPanel getInputPanel() { + JPanel inputData = new JPanel (new GridBagLayout()); + inputData.setBorder (createFatBorder + ("Service Input Data", + GraphColours.getColour ("cadetblue", Color.blue))); + + // upper part (tables, input file, show-xml check-box) + JPanel upper = new JPanel (new GridBagLayout()); + + dataTablesPanel = new JPanel (new GridBagLayout()); + + iFromFile = createDataBox ("Take an input from this XML file", DP_SC_IN_FILE, false); + inFile = createFileSelector ("Select input XML for calling a service", + "Select", + null, + DP_SC_INPUT_FILE, + DP_SC_INPUT_FILE); + inFile.setEnabled (iFromFile.isSelected()); + + iShowXML = createDataBox ("Show input as XML", DP_INP_SHOWXML, true); + + SwingUtils.addComponent (upper, dataTablesPanel, 0, 0, 2, 1, BOTH, NWEST, 1.0, 1.0); + SwingUtils.addComponent (upper, iFromFile, 0, 1, 1, 1, NONE, NWEST, 0.0, 0.0); + SwingUtils.addComponent (upper, inFile, 1, 1, 1, 1, HORI, NWEST, 1.0, 0.0); + SwingUtils.addComponent (upper, iShowXML, 0, 2, 1, 1, NONE, NWEST, 0.0, 0.0); + + // lower part (console showing/editing input XML) + input = new EditableConsole(); + input.setAppendMode (false); + input.setVerboseMode (false); + + // split upper and lower parts into moving panels + JSplitPane split = vSplit (upper, input, 0.5); + SwingUtils.addComponent (inputData, split, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + return inputData; + } + + class EditableConsole + extends CommonConsole { + + public EditableConsole() { + super(); + textArea.setEditable (true); + textArea.setBackground + (GraphColours.getColour (DashboardConfig.getString (P_S_EDIT_BGCOLOR, null), + textArea.getBackground())); + } + } + + /************************************************************************** + * Replace the global 'dataTablesPanel' with an information text. + **************************************************************************/ + protected void updateInputDataPanel (String info) { + dataTablesPanel.removeAll(); + AwtUtils.redisplay (dataTablesPanel); + + JLabel text = new JLabel (info); + SwingUtils.addComponent (dataTablesPanel, text, 0, 0, 1, 1, NONE, CENTER, 0.0, 0.0); + dataTablesPanel.validate(); + return; + } + + /************************************************************************** + * Replace the global 'dataTablesPanel' with fields defining the + * input data for the given service. + **************************************************************************/ + protected void updateInputDataPanel (MobyService service, + MobyDataType[] dataTypes) { + dataTablesPanel.removeAll(); + + inputDataTables = new ServiceInputPanel (service, dataTypes); + SwingUtils.addComponent (dataTablesPanel, inputDataTables, 0, 0, 1, 1, BOTH, NWEST, 1.0, 1.0); + dataTablesPanel.validate(); + } + + /************************************************************************** + * Find 'dataTypeToBeFound in 'dataTypes' and return it. The same + * could be achieved by calling registryModel.getDataType() but + * here I do not want to create yet another swing worker for it. + **************************************************************************/ + protected MobyDataType findDataType (String dataTypeToBeFound, + MobyDataType[] dataTypes) { + for (int i = 0; i < dataTypes.length; i++) { + if (dataTypeToBeFound.equals (dataTypes[i].getName())) + return dataTypes[i]; + } + log.error ("Strange, data type '" + dataTypeToBeFound + + "' was not found in " + dataTypes.length + " data types."); + return null; + } + + /************************************************************************** + * + * A worker that calls the service... + * + **************************************************************************/ + class MySwingWorker + extends SwingWorker { + + MobyException exception = null; + DataContainer data = new DataContainer(); + boolean wasCancelled = false; + MobyService service; + + public MySwingWorker (MobyService service) { + super(); + this.service = service; + data.setMetadata (propertyChannel); + } + + public void cancel() { + wasCancelled = true; + propertyChannel.fire (DP_STATUS_MSG, "Service invocation cancelled."); + } + + public Object construct() { + try { + runButton.setEnabled (false); + propertyChannel.fire (DP_STATUS_MSG, + "Calling service " + service.getName() + "..."); + + // create a data container with input data... + if (propertyChannel.getBoolean (DP_SC_IN_FILE, false)) { + + // ...either from a file + String inputFile = propertyChannel.getString (DP_SC_INPUT_FILE); + if (UUtils.isEmpty (inputFile)) + throw new MobyException ("No input XML file given."); + data.setDataFromFile (new File (inputFile)); + + } else { + data.setData (inputDataTables.toXML()); + } + + // optionally, show XML data: we want to show this XML + // input only (a) if it was explicitly asked for (property + // DP_INP_SHOWXML is true), or (b) if "no real service + // call" was selected (property DP_CALL_SERVICE has value + // DP_CS_NONE) + if ( DP_CS_NONE.equals (propertyChannel.getString (DP_CALL_SERVICE)) || + (propertyChannel.getBoolean (DP_INP_SHOWXML, false)) ) { + input.setText ((String)data.getData()); + } + + // If we are only pinging the service, set the data object to an empty message + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + String emptyMsg = "\n" + + "\n" + + " \n" + + ""; + data.setData(emptyMsg); + input.setText(emptyMsg); + } + + // finally, call the service + stopButton.setEnabled (true); + callerModel.runIt (data); + + } catch (MobyException e) { + exception = e; + + } catch (Error e) { + exception = new MobyException (e.toString()); + } + return null; // not used here + } + + // runs on the event-dispatching thread + public void finished() { + if (wasCancelled) { + // service was interrupted by the Stop button - do + // nothing (the whole GUI should be already in a good + // state - the button 'Stop' took care about it) + return; + } + + if (exception == null) { + + // handle results here (using renderers...) + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + propertyChannel.fire (DP_STATUS_MSG, service.getName()+" isAlive."); + } else { + propertyChannel.fire (DP_STATUS_MSG, "Service invocation finished."); + } + + if (! DP_CS_NONE.equals (propertyChannel.getString (DP_CALL_SERVICE))) { + results.updateComponent (data); + } + + } else { + if (propertyChannel.getString(DP_INP_PING).toLowerCase().equals("true")) { + propertyChannel.fire (DP_STATUS_MSG, service.getName()+" is dead."); + results.removeResults(); + } else { + propertyChannel.fire (DP_STATUS_MSG, "Service invocation failed."); + error (CALLER_ERROR, exception); + } + exception.printStackTrace(); + } + serviceFinished(); + } + } + + /************************************************************************** + * Called when a call to a service finished. + **************************************************************************/ + protected void serviceFinished() { + runButton.setEnabled (true); + stopButton.setEnabled (false); + } + + /************************************************************************** + * Called when a service is selected in a service tree (or in a + * 'recently used services' combo box), and also at the beginning + * when a service name is retrieved from user preferences. + * + * Get selected service from a registry model and generate a new + * 'input data panel' to reflect input data of the selected + * service. + **************************************************************************/ + protected void selectService (final String serviceName) { + final Object source = this; + final SwingWorker worker = new SwingWorker() { + MobyService service; + MobyDataType[] dataTypes; + public Object construct() { + try { + service = registryModel.getService (serviceName); + dataTypes = registryModel.getDataTypes (source); + } catch (MobyException e) { + error (ServicesTree.SERVICES_ACCESS_ERROR, e); + } + return service; // not used here + } + + // runs on the event-dispatching thread. + public void finished() { + if (service == null) { + deselectService(); + } else { + updateInputDataPanel (service, dataTypes); + selService.setText (service.getName()); +// selectionAllowed = false; +// recentServices.setText (service.getName()); +// selectionAllowed = true; + propertyChannel.put (DP_SC_SERVICE, service); + runButton.setEnabled (true); + + } + } + }; + worker.start(); + } + + /************************************************************************** + * Called when no service is selected in order to display this + * fact on various places in the panel. + **************************************************************************/ + protected void deselectService() { + selService.setText (""); + updateInputDataPanel (INIT_SELECT); + propertyChannel.remove (DP_SC_SERVICE); + runButton.setEnabled (false); + } + + /************************************************************************** + * + **************************************************************************/ + public String getName() { + return "Simple Client"; + } + + /************************************************************************** + * + **************************************************************************/ + public String getDescription() { + return + "A panel allowing to create input data and to call an arbitrary Biomoby service. " + + "Its purpose is mostly for the service developers to test their new services."; + } + + /************************************************************************** + * + * Customized tree of services... + * + **************************************************************************/ + protected class CustomServicesTree + extends ServicesTree { + + /********************************************************************* + * Construtor + ********************************************************************/ + public CustomServicesTree (RegistryModel model, + CommonConsole console) { + super (model, console); + } + + /********************************************************************* + * + ********************************************************************/ + protected void createPopups (String title) { + super.createPopups (title); + removeFromPopups (AC_RELOAD); + removeSeparatorAfter (AC_COLLAPSE); + } + + /********************************************************************* + * Service selected in a service tree... + ********************************************************************/ + protected void selected (DefaultMutableTreeNode node) { + if (node == null) { + // nothing selected + deselectService(); + return; + } + updateInputDataPanel ("Loading..."); + selService.setText (""); + final CommonNode nodeObject = (CommonNode)node.getUserObject(); + String currentServiceName = nodeObject.getValue(); + selectService (currentServiceName); + setPrefValue (DP_SC_SERVICE_NAME, currentServiceName); + } + } + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java 2008/11/26 08:54:21 1.7 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/ServiceCallerModel.java 2008/12/03 15:21:13 1.8 @@ -1,168 +1,180 @@ -// ServiceCallerModel.java -// -// Created: February 2006 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.service.dashboard; - -import org.apache.axis.client.Call; -import org.biomoby.client.ExtendedProtocolClient; -import org.biomoby.client.ExtendedServiceLocator; -import org.biomoby.client.MobyServiceLocator; -import org.biomoby.service.dashboard.data.DataContainer; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.parser.MobyJob; -import org.biomoby.shared.parser.MobyPackage; -import org.tulsoft.shared.UUtils; - -/** - * A model that achieves its task by calling (local, remote, or none) Biomoby service. It delegates the task of calling - * a service to a true Biomoby client (that extends BaseClient). - *

      - * - * @author Martin Senger - * @version $Id$ - */ - -public class ServiceCallerModel extends AbstractModel { - - // private static org.apache.commons.logging.Log log = - // org.apache.commons.logging.LogFactory.getLog (ServiceCallerModel.class); - - /******************************************************************************************************************* - * Call a service. This is the main purpose of this model. - *

      - * - * @param data - * contains input data and this method replaces them by result data - ******************************************************************************************************************/ - public void runIt( DataContainer data ) throws MobyException { - SimpleClient worker = new SimpleClient( data ); - worker.process(); - } - - /******************************************************************************************************************* - * - * A real client - the main worker for this model.. - * - ******************************************************************************************************************/ - protected class SimpleClient extends ExtendedProtocolClient { - - DataContainer data; - - /*************************************************************************************************************** - * Constructor. - **************************************************************************************************************/ - public SimpleClient( DataContainer data ) { - super(); - this.data = data; - } - - /*************************************************************************************************************** - * What service to call and where to find it. - **************************************************************************************************************/ - public MobyServiceLocator getServiceLocator() throws MobyException { - return new MyServiceLocator(); - } - - /*************************************************************************************************************** - * Not used here... - **************************************************************************************************************/ - public boolean fillRequest( MobyJob request, MobyPackage inputContext ) throws MobyException { - return true; - } - - /*************************************************************************************************************** - * Not used here... - **************************************************************************************************************/ - public boolean useResponse( MobyJob response, MobyPackage responseContext ) throws MobyException { - return true; - } - - /*************************************************************************************************************** - * Return input XML (from a data container obtained in the constructor). - **************************************************************************************************************/ - public String fillRequest() throws MobyException { - - if ( data == null ) throw new MobyException( "No input data given." ); - - return ( String ) data.getData(); - } - - /** - * Sets the authentication for the service call. If the user has checked the corresponding box in the Dashboard - * the values are stored in the propertychannel. - */ - protected void setAuthentication( Call call ) { - String user = propertyChannel.getString( DashboardProperties.DP_USER_AUTHENTICATION ); - if ( !isEmpty( user ) ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, new String( ( char[] ) propertyChannel - .get( DashboardProperties.DP_PASSWORD_AUTHENTICATION ) ) ); - } - } - - /*************************************************************************************************************** - * - **************************************************************************************************************/ - public boolean useResponse( String xmlResponse ) throws MobyException { - - data.setData( xmlResponse ); - - // do nothing more if it is just an input echo - if ( ( ( ExtendedServiceLocator ) getServiceLocator() ).isLoop() ) return false; - - return false; - } - } - - /******************************************************************************************************************* - * - * A service locator filled from the property channel. - * - ******************************************************************************************************************/ - protected class MyServiceLocator extends ExtendedServiceLocator { - - public MyServiceLocator() throws MobyException { - super(); - - // fill this locator by a service - MobyService selService = ( MobyService ) propertyChannel.get( DP_SC_SERVICE ); - if ( selService == null ) throw new MobyException( "No service given." ); - MobyService clonedService = new MobyService( selService.getName(), selService.getAuthority() ); - clonedService.setURL( selService.getURL() ); - setService( clonedService ); - - // fill how to call this service - String howToCall = propertyChannel.getString( DP_CALL_SERVICE ); - if ( DP_CS_NEWURL.equals( howToCall ) ) { - String sEndpoint = propertyChannel.getString( DP_ENDPOINT ); - if ( !UUtils.isEmpty( sEndpoint ) ) clonedService.setURL( sEndpoint ); - - } - else if ( DP_CS_REGISTRY.equals( howToCall ) ) { - clonedService.setURL( null ); - setRegistryEndpoint( propertyChannel.getString( DP_REGISTRY_ENDPOINT ) ); - setRegistryNamespace( propertyChannel.getString( DP_REGISTRY_NAMESPACE ) ); - - } - else if ( DP_CS_CLASS.equals( howToCall ) ) { - String localClass = propertyChannel.getString( DP_IMPL_CLASS ); - if ( UUtils.isEmpty( localClass ) ) throw new MobyException( "No local class given." ); - setLocalClass( localClass ); - - } - else if ( DP_CS_NONE.equals( howToCall ) ) { - setLoop( true ); - } - - setAsBytes( propertyChannel.getBoolean( DP_INP_ASBYTES, false ) ); - - } - } - -} +// ServiceCallerModel.java +// +// Created: February 2006 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.service.dashboard; + +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.parser.MobyPackage; +import org.biomoby.shared.parser.MobyJob; +import org.biomoby.client.ExtendedProtocolClient; +import org.biomoby.client.MobyServiceLocator; +import org.biomoby.client.ExtendedServiceLocator; +import org.biomoby.service.dashboard.data.DataContainer; + +import org.tulsoft.shared.UUtils; + +/** + * A model that achieves its task by calling (local, remote, or none) + * Biomoby service. It delegates the task of calling a service to a + * true Biomoby client (that extends BaseClient).

      + * + * @author Martin Senger + * @version $Id$ + */ + +public class ServiceCallerModel + extends AbstractModel { + +// private static org.apache.commons.logging.Log log = +// org.apache.commons.logging.LogFactory.getLog (ServiceCallerModel.class); + + /************************************************************************** + * Call a service. This is the main purpose of this model.

      + * + * @param data contains input data and this method replaces them + * by result data + *************************************************************************/ + public void runIt (DataContainer data) + throws MobyException { + SimpleClient worker = new SimpleClient (data); + worker.process(); + } + + /************************************************************************** + * + * A real client - the main worker for this model.. + * + *************************************************************************/ + protected class SimpleClient + extends ExtendedProtocolClient { + + DataContainer data; + + /************************************************************************** + * Constructor. + *************************************************************************/ + public SimpleClient (DataContainer data) { + super(); + this.data = data; + } + + /************************************************************************** + * What service to call and where to find it. + *************************************************************************/ + public MobyServiceLocator getServiceLocator() + throws MobyException { + return new MyServiceLocator(); + } + + /************************************************************************** + * Not used here... + *************************************************************************/ + public boolean fillRequest (MobyJob request, MobyPackage inputContext) + throws MobyException { + return true; + } + + /************************************************************************** + * Not used here... + *************************************************************************/ + public boolean useResponse (MobyJob response, + MobyPackage responseContext) + throws MobyException { + return true; + } + + /************************************************************************** + * Return input XML (from a data container obtained in the + * constructor). + *************************************************************************/ + public String fillRequest() + throws MobyException { + + if (data == null) + throw new MobyException ("No input data given."); + + return (String)data.getData(); + } + + /************************************************************************** + * + *************************************************************************/ + public boolean useResponse (String xmlResponse) + throws MobyException { + + data.setData (xmlResponse); + + // do nothing more if it is just an input echo + if ( ((ExtendedServiceLocator)getServiceLocator()).isLoop()) + return false; + + return false; + } + } + + /************************************************************************** + * + * A service locator filled from the property channel. + * + *************************************************************************/ + protected class MyServiceLocator + extends ExtendedServiceLocator { + + public MyServiceLocator() + throws MobyException { + super(); + + // fill this locator by a service + MobyService selService = (MobyService)propertyChannel.get (DP_SC_SERVICE); + if (selService == null) + throw new MobyException ("No service given."); + MobyService clonedService = new MobyService (selService.getName(), selService.getAuthority()); + clonedService.setURL (selService.getURL()); + setService (clonedService); + + // fill how to call this service + String howToCall = propertyChannel.getString (DP_CALL_SERVICE); + if (DP_CS_NEWURL.equals (howToCall)) { + String sEndpoint = propertyChannel.getString (DP_ENDPOINT); + if (! UUtils.isEmpty (sEndpoint)) + clonedService.setURL (sEndpoint); + + } else if (DP_CS_REGISTRY.equals (howToCall)) { + clonedService.setURL (null); + setRegistryEndpoint (propertyChannel.getString (DP_REGISTRY_ENDPOINT)); + setRegistryNamespace (propertyChannel.getString (DP_REGISTRY_NAMESPACE)); + + } else if (DP_CS_CLASS.equals (howToCall)) { + String localClass = propertyChannel.getString (DP_IMPL_CLASS); + if (UUtils.isEmpty (localClass)) + throw new MobyException ("No local class given."); + setLocalClass (localClass); + + } else if (DP_CS_NONE.equals (howToCall)) { + setLoop (true); + } + + setAsBytes (propertyChannel.getBoolean (DP_INP_ASBYTES, false)); + + // sets the user and the password + // the getString method returns an empty string in case the + // key is not in the propertychannel, therefore the test if + // the value is not empty + String user = propertyChannel.getString(DP_USER_AUTHENTICATION); + if(user.length() > 0) { + setUser( user ); + } + String password = propertyChannel.getString(DP_PASSWORD_AUTHENTICATION); + if(password.length() > 0) { + setPassword( password ); + } + } + } + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java,v retrieving revision 1.30 retrieving revision 1.31 diff -u -r1.30 -r1.31 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java 2008/11/26 08:54:21 1.30 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/dashboard/DashboardProperties.java 2008/12/03 15:21:13 1.31 @@ -9,10 +9,10 @@ package org.biomoby.service.dashboard; /** - * A list of names of most/all recognized properties that can be fired by dashboard panels, and a list of names of Java - * properties that can be used to configure the dashboard. - *

      - * + * A list of names of most/all recognized properties that can be fired + * by dashboard panels, and a list of names of Java properties that + * can be used to configure the dashboard.

      + * * @author Martin Senger * @version $Id$ */ @@ -44,9 +44,9 @@ static final String DP_FL_BIOCASE = "biocase"; static final String DP_FL_HIBERNATE = "hibernate"; - static final String DP_SEL_SERVICES = "selectedServices"; // type: Vector with service/authority name - static final String DP_SEL_AUTHORITIES = "selectedAuthorities"; // type: Vector with authority name - static final String DP_DEPL_SERVICES = "servicesToDeploy"; // type: Map with serviceName => className + static final String DP_SEL_SERVICES = "selectedServices"; // type: Vector with service/authority name + static final String DP_SEL_AUTHORITIES = "selectedAuthorities"; // type: Vector with authority name + static final String DP_DEPL_SERVICES = "servicesToDeploy"; // type: Map with serviceName => className static final String DP_LOCAL_DEPLOY = "use-local-deploy"; static final String DP_TOMCAT_HOME = "tomcatHome"; @@ -82,10 +82,10 @@ static final String DP_DETACH_VIEW = "detachViewers"; - // static final String DP_SC_IN_DATA = "sc-inputData"; +// static final String DP_SC_IN_DATA = "sc-inputData"; static final String DP_SC_IN_FILE = "sc-inputFromFile"; static final String DP_SC_INPUT_FILE = "sc-inputFile"; - static final String DP_SC_SERVICE = "dp-sc-service"; // type: MobyService + static final String DP_SC_SERVICE = "dp-sc-service"; // type: MobyService static final String DP_SC_SERVICE_NAME = "dp-sc-service-name"; static final String DP_SC_SERVICES = "dp-sc-recent-services"; @@ -97,21 +97,21 @@ static final String DP_DATATYPE_NAME = "dp-datatype-name"; // names of properties used in property channel storage - static final String DP_REGISTRY_MODEL = "dp-registry-model"; // type: RegistryModel - static final String DP_ANT_MODEL = "dp-ant-model"; // type: AntModel + static final String DP_REGISTRY_MODEL = "dp-registry-model"; // type: RegistryModel + static final String DP_ANT_MODEL = "dp-ant-model"; // type: AntModel static final String DP_REGISTRY_SYNONYM = "dp-registry-synonym"; - static final String DP_REG_INFO = "dp-reg-info"; // type: Boolean + static final String DP_REG_INFO = "dp-reg-info"; // type: Boolean static final String DP_REGISTRY_ENDPOINT = "dp-registry-endpoint"; static final String DP_REGISTRY_NAMESPACE = "dp-registry-namespace"; static final String DP_CACHE_DIR = "dp-cache-dir"; - static final String DP_USE_CACHE = "dp-use-cache"; // type: Boolean + static final String DP_USE_CACHE = "dp-use-cache"; // type: Boolean static final String DP_REG_DT_NAME = "dp-reg-dt-name"; static final String DP_REG_DT_AUTH = "dp-reg-dt-auth"; static final String DP_REG_DT_EMAIL = "dp-reg-dt-email"; static final String DP_REG_DT_DESC = "dp-reg-dt-desc"; - static final String DP_REG_DT_TREE = "dp-reg-dt-tree"; // type: MobyDataType + static final String DP_REG_DT_TREE = "dp-reg-dt-tree"; // type: MobyDataType static final String DP_REG_NS_NAME = "dp-reg-ns-name"; static final String DP_REG_NS_AUTH = "dp-reg-ns-auth"; @@ -132,88 +132,97 @@ static final String DP_REG_S_RDF_URL = "dp-reg-s-rdf-url"; static final String DP_REG_S_RDF_PATH = "dp-reg-s-rdf-path"; static final String DP_REG_S_XML_PATH = "dp-reg-s-xml-path"; - static final String DP_USE_SIGNATURE = "dp-use-signature"; // type: Boolean - static final String DP_USE_AUTHORITATIVE = "dp-use-auth"; // type: Boolean + static final String DP_USE_SIGNATURE = "dp-use-signature"; // type: Boolean + static final String DP_USE_AUTHORITATIVE = "dp-use-auth"; // type: Boolean static final String DP_REG_S_TYPE = "dp-reg-s-type"; static final String DP_REG_VERBOSE = "dp-reg-verbose"; - static final String DP_S_SELECTED = "dp-s-selected"; // type: MobyService + static final String DP_S_SELECTED = "dp-s-selected"; // type: MobyService - /** - * A property name. Its value contains a title that will appear in big fonts on top of the dashboard. It may be - * empty if property {@link #DP_TITLE_ICON} is defined; otherwise a default value will be used. + /** A property name. Its value contains a title that will appear + * in big fonts on top of the dashboard. It may be empty if + * property {@link #DP_TITLE_ICON} is defined; otherwise a default + * value will be used. */ static final String DP_TITLE = "dashboard.title"; - /** - * A property name. Its value contains a filename with an icon accompanying a dashboard title (defined by property - * {@link #DP_TITLE}. No default value used. Specify here either an absolute path (not recommended) or a relative - * path whose beginning can be found somewhere on the CLASSPATH. + /** A property name. Its value contains a filename with an icon + * accompanying a dashboard title (defined by property {@link + * #DP_TITLE}. No default value used. Specify here either an + * absolute path (not recommended) or a relative path whose + * beginning can be found somewhere on the CLASSPATH. */ static final String DP_TITLE_ICON = "dashboard.title.icon"; - /** - * A property name. Its value contains a filename with the main dashboard icon. Specify here either an absolute path - * (not recommended) or a relative path whose beginning can be found somewhere on the CLASSPATH. + /** A property name. Its value contains a filename with the main + * dashboard icon. Specify here either an absolute path (not + * recommended) or a relative path whose beginning can be found + * somewhere on the CLASSPATH. */ static final String DP_ICON = "dashboard.icon"; - /** - * A property name. Its value contains a color name used to paint main dashboard background. The name can be a color - * name, or a number in various format (see GraphColours for details). + /** A property name. Its value contains a color name used to paint + * main dashboard background. The name can be a color name, or a + * number in various format (see GraphColours for + * details). */ static final String DP_BGCOLOR = "dashboard.bgcolor"; - /** - * A property name. Its value contains a short description what a dashboard can do generally. Often, however, it is - * more convenient to put the description in a file and to use property {@link #DP_DESCRIPTION_FILE}. + /** A property name. Its value contains a short description what a + dashboard can do generally. Often, however, it is more + convenient to put the description in a file and to use + property {@link #DP_DESCRIPTION_FILE}. */ static final String DP_DESCRIPTION = "dashboard.description"; - /** - * A property name. Its value contains a file name with a short description what a dashboard can do generally. + /** A property name. Its value contains a file name with a short + description what a dashboard can do generally. */ static final String DP_DESCRIPTION_FILE = "dashboard.description.file"; - /** - * A property name. Its value contains a short description of a project that uses this dashboard. Often, however, it - * is more convenient to put the description in a file and to use property {@link #DP_P_DESCRIPTION_FILE}. + /** A property name. Its value contains a short description of a + project that uses this dashboard. Often, however, it is more + convenient to put the description in a file and to use + property {@link #DP_P_DESCRIPTION_FILE}. */ static final String DP_P_DESCRIPTION = "project.description"; - /** - * A property name. Its value contains a file name with a short description of a project that uses this dashboard. + /** A property name. Its value contains a file name with a short + description of a project that uses this dashboard. */ static final String DP_P_DESCRIPTION_FILE = "project.description.file"; - /** - * A property name. Its value contains a name of a contact person, possibly with an email address. + /** A property name. Its value contains a name of a contact + person, possibly with an email address. */ static final String DP_CONTACT = "dashboard.contact"; - /** - * A property name. Its value contains a directory name with the local cache of a BiMoby Central registry. + /** A property name. Its value contains a directory name with the + * local cache of a BiMoby Central registry. */ static final String DP_REGISTRY_CACHE_DIR = "registry.cache.dir"; - /** - * A property name. Its value contains a name or a comma-separated list of names of BioMoby registries that will be - * displayed in the RegistryPanel. If this property is missing, the list is taken from the hard-coded known - * registries in the Java source file. - *

      - * - * The names (values of this property) are equivalent to the 'synonym' attribute of the Registry class. + /** A property name. Its value contains a name or a + * comma-separated list of names of BioMoby registries that will + * be displayed in the RegistryPanel. If this property is missing, + * the list is taken from the hard-coded known registries in the + * Java source file.

      + * + * The names (values of this property) are equivalent to the + * 'synonym' attribute of the Registry class. */ static final String DP_WANTED_REGISTRIES = "dashboard.wanted.registries"; - /** - * A property name. Its value contains a name (synonym) of a default BioMoby registry. By default, the default - * registry is taken either from the first element in {@link #DP_WANTED_REGISTRIES} or from + /** A property name. Its value contains a name (synonym) of a + * default BioMoby registry. By default, the default registry is + * taken either from the first element in {@link + * #DP_WANTED_REGISTRIES} or from * Registries.DEFAULT_REGISTRY_SYNONYM. */ static final String DP_DEFAULT_REGISTRY = "dashboard.default.registry"; + /** * A property name. Its value contains the user name used for the authentication required for the servlet container * the service is hosted at. From groscurt at dev.open-bio.org Wed Dec 3 15:21:13 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 10:21:13 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031521.mB3FLD8Y013747@dev.open-bio.org> groscurt Wed Dec 3 10:21:13 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv13676/src/main/org/biomoby/client Modified Files: MobyRequest.java BaseClient.java MobyServiceLocator.java Log Message: changes made for the authentication... without formatting this time moby-live/Java/src/main/org/biomoby/client MobyRequest.java,1.41,1.42 BaseClient.java,1.13,1.14 MobyServiceLocator.java,1.4,1.5 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java,v retrieving revision 1.41 retrieving revision 1.42 diff -u -r1.41 -r1.42 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java 2008/11/26 08:53:43 1.41 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyRequest.java 2008/12/03 15:21:13 1.42 @@ -1,1028 +1,1030 @@ - -package org.biomoby.client; - -import java.io.*; -import java.util.*; - -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.rpc.Service; -import javax.xml.transform.TransformerException; - -import org.apache.axis.client.Call; -import org.apache.axis.message.MessageElement; -import org.apache.xml.utils.PrefixResolver; -import org.apache.xml.utils.PrefixResolverDefault; -import org.apache.xpath.XPath; -import org.apache.xpath.XPathContext; -import org.apache.xpath.objects.XNodeSet; -import org.apache.xpath.objects.XObject; - -import org.biomoby.shared.*; -import org.biomoby.shared.data.*; -import org.biomoby.shared.parser.MobyTags; // defined the Moby XML element names -import org.biomoby.w3c.addressing.EndpointReference; -import org.omg.lsae.notifications.AnalysisEvent; - -import org.w3c.dom.*; - -/** - * This class handles the WSDL transaction to request a response from a remote SOAP Web service that handles the MOBY format. It depends on having already retrieved the definition of the Web - * service via the MOBY central registry using the jMOBY - * API, and for now it uses the Apache Axis Web services framework, - * as well as Apache Xalan. There are code comments for the few lines that rely on Axis classes rather than the JAX-RPC - * interfaces. - * - * @author Paul Gordon gordonp at ucalgary.ca - */ -public class MobyRequest { - - protected MobyService mobyService = null; - protected MobyContentInstance inputData = null; - protected MobyContentInstance outputData = null; - protected Central mobyCentral = null; - protected PrefixResolver mobyPrefixResolver = null; - - protected Hashtable wsdlCache = null; - protected String lastWsdlCacheKey = null; - protected DocumentBuilder docBuilder = null; - protected Service service = null; - - protected Class stringType; - protected static boolean debug = false; - protected PrintStream debugPS = System.err; - protected XPathContext xpath_context; - protected String responseString = null; - - private XPath stringEncodedXPath; - private XPath base64EncodedXPath; - private XPath simpleChildXPath; - private XPath collectionChildXPath; - - private int autoID = 0; - - // Used as invocation callback if MobyRequest is acting as a server, - // or is executing services as a client asynchronously - private Vector< MobyRequestEventHandler > eventHandlers; - - private String user; - private String password; - - /** - * Default constructor. You should have a Central instance around since you're going to be retrieving MobyServices - * to pass into here. Lets reuse it. - * - * @param central An instance of a Moby central object so we can make requests about object types, etc. - * @throws ParserConfigurationException if JAXP doesn't have any valid DOM-building XML parsers set up for use - */ - public MobyRequest( Central central ) throws ParserConfigurationException { - mobyCentral = central; - wsdlCache = new Hashtable(); - - eventHandlers = new Vector< MobyRequestEventHandler >(); - - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware( true ); - docBuilder = dbf.newDocumentBuilder(); - - try { - stringType = Class.forName( "java.lang.String" ); - } - catch ( ClassNotFoundException classe ) { - debugPS.println( "WARNING: Something is very wrong, could not find Class definition of String: " + classe ); - } - - xpath_context = new XPathContext(); - mobyPrefixResolver = new MobyPrefixResolver(); - - // Now compile the XPath statements that will be used fetch data from the server response - try { - base64EncodedXPath = new XPath( "//*[starts-with(substring-after(@" + MobyPrefixResolver.XSI1999_PREFIX - + ":type, ':'), \"base64\") or starts-with(substring-after(@" + MobyPrefixResolver.XSI2001_PREFIX - + ":type, ':'), \"base64\")]", null, mobyPrefixResolver, XPath.SELECT ); - stringEncodedXPath = new XPath( "//*[substring-after(@" + MobyPrefixResolver.XSI1999_PREFIX - + ":type, ':')=\"string\" or substring-after(@" + MobyPrefixResolver.XSI2001_PREFIX - + ":type, ':')=\"string\"] | //" + MobyPrefixResolver.SOAP_ENC_PREFIX + ":string", null, - mobyPrefixResolver, XPath.SELECT ); - simpleChildXPath = new XPath( "moby:Simple | Simple", null, mobyPrefixResolver, XPath.SELECT ); - collectionChildXPath = new XPath( "moby:Collection | Collection", null, mobyPrefixResolver, XPath.SELECT ); - } - catch ( TransformerException te ) { - debugPS.println( "Syntax error encountered while compiling XPath " - + "statements for internal use (code bug?): " + te ); - } - setDebugMode( System.getProperty( "moby.debug" ) != null ); - } - - /** - * @param mode if true, debugging information is printed to the stream returned by getDebugOutputStream - */ - public void setDebugMode(boolean mode) { - debug = mode; - } - - /** - * Standard error is used unless this method is called. - * - * @param ps the OutputStream to which debugging information is sent. - * @throws IllegalArgumentException if the stream is null - */ - public void setDebugPrintStream(PrintStream ps) throws IllegalArgumentException { - if ( ps == null ) { - throw new IllegalArgumentException( "The OutputStream specified to MobyRequest was null" ); - } - debugPS = ps; - } - - /** - * @param user the user for a possible service authentication - * @param password the passoword for a possible service authentication - */ - public void setAuthentication(String user, String password) { - this.user = user; - this.password = password; - } - - /** - * @return the instance of the class implementing Central that we are using - */ - public Central getCentralImpl() { - return mobyCentral; - } - - /** - * @param mobyservice the MobyService that should be executed when invokeService is called - */ - public void setService(MobyService mobyservice) { - if ( mobyservice == null ) { - mobyService = null; - } - else if ( mobyService == null || !mobyservice.equals( mobyService ) ) { - mobyService = mobyservice; - } - } - - /** - * @return the MobyService that will be executed when invokeService is called - */ - public MobyService getService() { - return mobyService; - } - - /** - * @return the Raw MOBY XML response as a string - */ - public String getResponseXML() { - return responseString; - } - - /** - * Sets the input data for the MOBY service request. The length of the input array, and the number of input - * parameters required by the service must be equal when invokeService() is called. This method strictly enforces - * that the input be of the appropriate type for the service. - * - * Note that there is no requirement to use MobyDataInstance.setXmlMode() before passing in data, this class will - * temporarily set the XML mode of the data when it is required. - * - * @throws IllegalArgumentException if the input does not fit the criteria of the service (e.g. wrong data type) - */ - public void setInput(MobyContentInstance data) throws MobyException { - inputData = data; - } - - /** - * Takes the data in the array, with their current articleNames, as input for the service - */ - public void setInput(MobyDataInstance[] data) throws MobyException { - MobyDataJob job = new MobyDataJob(); - for ( MobyDataInstance param : data ) { - job.put( param.getName(), param ); - } - inputData = new MobyContentInstance(); - inputData.put( job ); - } - - /** - * Convenience method to run services that take one argument. If the service requires the input to have a name, it - * will be automatically assigned. - */ - public void setInput(MobyDataInstance datum) throws MobyException { - setInput( datum, "" ); - } - - /** - * Convenience method to run services that take one named argument. - */ - public void setInput(MobyDataInstance datum, String paramName) throws MobyException { - inputData = new MobyContentInstance( datum, paramName ); - } - - /** - * @return the MobyService that will be executed when invokeService is called - */ - public MobyContentInstance getInput() { - return inputData; - } - - /** - * Same functionality as setSecondaryInput(MobyDataSecondaryInstance[]) - */ - public void setSecondaryInput(Collection< MobyDataSecondaryInstance > secondaryData) throws MobyException { - setSecondaryInput( secondaryData.toArray( new MobyDataSecondaryInstance[ secondaryData.size() ] ) ); - } - - /** - * This method will assign the provided secondary parameters to all primary input data currently in this object. - * This is covenient if you are running 100 seqs through BLAST and only want to set the parameters once. If you - * instead want to set secondary input differently for all primary inputs, you'll need to create a custom - * MobyContentInstance as input to setInput(). - * - * @throws MobyException if a parameter name is blank, or overrides a primary parameter - */ - public void setSecondaryInput(MobyDataSecondaryInstance[] secondaryData) throws MobyException { - - Iterator queryNames = inputData.keySet().iterator(); - // For each query - while (queryNames.hasNext()) { - MobyDataJob queryParams = inputData.get( queryNames.next() ); - // Set all the secondary params (overwrites any old ones) - for ( int i = 0; i < secondaryData.length; i++ ) { - String secName = secondaryData[ i ].getName(); - if ( secName == null || secName.length() == 0 ) { - throw new MobyException( "A secondary parameter cannot have a blank name (array index " + i + ")" ); - } - if ( queryParams.containsKey( secName ) && queryParams.get( secName ) instanceof MobyPrimaryData ) { - throw new MobyException( "A secondary parameter cannot override an existing primary parameter " - + "with the same name (" + secName + ")" ); - } - queryParams.put( secName, secondaryData[ i ] ); - } - } - } - - /** - * @return a vector of MobyDataInstance[], each element of the vector is the collection of response objects for the - * correspondingly indexed input request. - * - * @throws MobyException if you try to get the results before calling InvokeService - */ - public MobyContentInstance getOutput() throws MobyException { - if ( outputData == null ) { - throw new MobyException( "Trying to access MOBY service results " + "before the service is invoked" ); - } - else { - return outputData; - } - } - - /** - * The main method of the class. If all of the MOBY input objects are properly defined according to the Web service - * definition, a SOAP request will be sent to the remote server, and the method will return one or more MOBY objects - * (synchronous). Call this method after calling setService, and setInput. If you do not call setSecondaryInput, the - * default secondary parameter values will be used. - * - * @return the results of the remote Web service in response to the give input - * - * @throws MobyException i.e. there was something wrong with the input, output or remote service's logic - * @throws SOAPException i.e. there was a problem with the underlying transaction/transport layer - */ - public MobyContentInstance invokeService() throws Exception, MobyException, SOAPException, NoSuccessException { - return mobyService.isAsynchronous() - ? invokeService( inputData, new StringBuffer() ) - : invokeService( inputData, ( StringBuffer ) null ); - } - - // Used internally for asynchronous thread calls that all need the XML data - // and can't rely on the answer from thread-insensitive getResponseXML() - private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML) throws Exception, - MobyException, SOAPException, NoSuccessException { - return invokeService( inData, contentsXML, null, 0 ); - } - - private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML, - MobyRequestEventHandler handler, int requestId) throws Exception, MobyException, SOAPException, - NoSuccessException { - - if ( mobyService == null ) { - throw new MobyException( "Tried to invoke null service from MobyRequest (call setService first)" ); - } - - Element mobyDOM = null; - if ( mobyService.isAsynchronous() ) { - // Async is "simpler", because it had to merge DOMs together into a single MobyContentInstance anyway - MobyContentInstance mci = performAsyncSOAPRequest( mobyService, inData, handler, requestId ); - StringWriter writer = new StringWriter(); - MobyDataUtils.toXMLDocument( writer, mci ); - contentsXML.append( writer.toString() ); - return mci; - } - else { - String mobyXML = convertMOBYDataToMOBYRequest( inData ); - Call call = getServiceFromWSDL(); - if ( user != null && password != null ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, password ); - } - mobyDOM = performSOAPRequest( call, mobyXML, contentsXML ); - // The following parses the DOM and extracts all the appropriate jMOBY objects to represent the XML in Java - return MobyDataUtils.fromXMLDocument( mobyDOM, mobyService.getServiceType().getRegistry() ); - } - } - - protected MobyContentInstance performAsyncSOAPRequest(MobyService mservice, MobyContentInstance inData, - MobyRequestEventHandler handler, int requestId) throws Exception { - String mobyXML = convertMOBYDataToMOBYRequest( inData ); - EndpointReference epr = AsyncClient.sendRequest( mservice, mobyXML ); - - // Essentially cloning, so removing ids doesn't change the - // MobyContentInstance "data" (which we will use again later on) - MobyContentInstance finalContents = new MobyContentInstance(); - Set< String > queryIDs = new HashSet< String >( inData.keySet() ); - try { - // Should add some timeout here... - while (!queryIDs.isEmpty()) { - // todo: make this setable - Thread.sleep( 5000 ); - - AnalysisEvent[] events = AsyncClient.poll( epr, queryIDs ); - - Vector< String > newDataAvailable = new Vector< String >(); - for ( AnalysisEvent event : events ) { - if ( event != null && event.isCompleted() ) { - queryIDs.remove( event.getQueryId() ); - newDataAvailable.add( event.getQueryId() ); - } - } - - if ( newDataAvailable.size() > 0 ) { - // Parse and merge the new data into the existing contents - InputStream resultStream = AsyncClient.getResultStream( epr, newDataAvailable ); - Element mobyDOM = asyncSoapTextToMobyDOM( resultStream ); - MobyContentInstance newResults = MobyDataUtils.fromXMLDocument( mobyDOM, - mservice.getServiceType() - .getRegistry() ); - // The merge - for ( String jobid : newResults.keySet() ) { - finalContents.put( jobid, newResults.get( jobid ) ); - } - - // Inform the handler that some data has been added to the response (for incremental display?) - if ( handler != null ) { - MobyRequestEvent mre = new MobyRequestEvent( finalContents, this, mservice, null, requestId ); - StringWriter xmlWriter = new StringWriter(); - MobyDataUtils.toXMLDocument( xmlWriter, finalContents ); - - mre.setContentsXML( xmlWriter.toString() ); - if ( !queryIDs.isEmpty() ) { - // Send an update event only if we aren't finished yet. - // If we are finished, the client is going to get this event as the - // invocation thread finishes up (no need to double up). - handler.processEvent( mre ); - } - } - } - } - } - catch ( Exception e ) { - e.printStackTrace(); - AsyncClient.destroy( epr ); - throw new Exception( "Exception occured while polling the service invocation: " + e ); - } - - return finalContents; - } - - private Element asyncSoapTextToMobyDOM(InputStream inStream) throws Exception { - Element soapDOM = null; - synchronized ( docBuilder ) { - soapDOM = docBuilder.parse( inStream ).getDocumentElement(); - } - final boolean IS_ASYNC_SERVICE_CALL = true; - return decodeSOAPMessage( soapDOM, null, null, IS_ASYNC_SERVICE_CALL ); - } - - /** - * Asynchronous call to invokeService. A callback to the passed-in handler will be made when the response is ready, - * or there is an exception. - * - * @return the id that the callback event will return from getID(), allowing a client to distinguish between - * multiple concurrent invocation callbacks - */ - public synchronized int invokeService(MobyRequestEventHandler handler) { - int id = autoID++; - - Thread t = new InvocationThread( this, inputData, handler, id ); // see internal class definition below - t.start(); - - return id; - } - - // This is the class that asynchronously calls the service and does a callback to - // the handler specified in the invocation. - class InvocationThread extends Thread { - MobyContentInstance data; - MobyService mservice; - MobyRequest mobyRequest; - MobyRequestEventHandler handler; - int requestId; - - InvocationThread( MobyRequest mr, MobyContentInstance inData, MobyRequestEventHandler h, int id ) { - data = inData; - mobyRequest = mr; - mservice = mobyRequest.getService(); - handler = h; - requestId = id; - - // Name the thread after the service being run, mostly for ease of debugging - setName( mservice.getName() + requestId ); - } - - public void run() { - MobyRequestEvent requestEvent = new MobyRequestEvent( data, mobyRequest, mservice, null, requestId ); - // Tell the handler we're starting the request, with the given data - handler.start( requestEvent ); - - MobyRequestEvent responseEvent = null; - MobyContentInstance content = null; - StringBuffer contentsXML = new StringBuffer(); // to be filled in by the RPC call below - try { - content = mobyRequest.invokeService( data, contentsXML, handler, requestId ); // RPC call... - } - catch ( Exception e ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, e, requestId ); - } - catch ( Error err ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, err, requestId ); - } - if ( responseEvent == null ) { - responseEvent = new MobyRequestEvent( content, mobyRequest, mservice, null, requestId ); - } - // We've got the raw XML laying around, so why not provide it unmolested to the callback? - responseEvent.setContentsXML( contentsXML.toString() ); - handler.processEvent( responseEvent ); - handler.stop( mobyRequest, requestId ); - } - } - - public void addEventHandler(MobyRequestEventHandler h) { - eventHandlers.add( h ); - } - - public void removeEventHandler(MobyRequestEventHandler h) { - eventHandlers.remove( h ); - } - - public void sendResponse(MobyRequestEvent mre) { - // Not yet implemented, need to conform to some web.xml specification here... - } - - /** - * This method retrieves from Moby Central a copy of the WSDL document for the service (or uses an internally cached - * copy from a previous invocation), and sets the variables for the SOAP call appropriately so you can consequently - * call performSOAPRequest. - */ - protected Call getServiceFromWSDL() throws MobyException, NoSuccessException { - // String wsdl = null; - - // // Since this is how we retrieve a service from Central, use the same values as the key to the hash - // String wsdlCacheKey = mobyService.getName() + "@" + mobyService.getAuthority(); - - // // This is the same call as last time, so we don't need to change the setup - // if(wsdlCacheKey.equals(lastWsdlCacheKey)){ - // return setCallFromWSDL((String) wsdlCache.get(wsdlCacheKey)); - // } - // // We haven't encountered this service yet - // else if(!wsdlCache.containsKey(wsdlCacheKey)){ - // wsdl = mobyCentral.getServiceWSDL(mobyService.getName(), mobyService.getAuthority()); - // wsdlCache.put(wsdlCacheKey, wsdl); - // } - // // We've dealt with this one before - // else{ - // wsdl = (String) wsdlCache.get(wsdlCacheKey); - // } - - // lastWsdlCacheKey = wsdlCacheKey; // Keep track of the last invocation - - // Get ready to do SOAP - return setCallFromWSDL( null ); - } - - /** - * Creates the SOAP Call that will be invoked later. This should be based on the WSDL document and parameter - * information from the MobyService, but these are currently not up to snuff. - */ - protected Call setCallFromWSDL(String wsdl) throws MobyException, SOAPException { - if ( service == null ) { - service = new org.apache.axis.client.Service(); // AXIS SPECIFIC This acts as a factory for Calls - } - - Call soapCall; - try { - soapCall = ( Call ) service.createCall();// create a fresh Call each time - } - catch ( javax.xml.rpc.ServiceException se ) { - throw new SOAPException( "Could not instatiate call to SOAP Service: " + se ); - } - - // Should initialize endpoint, etc. This call is AXIS SPECIFIC, otherwise you'll - // have to do the call's info setting manually. - // ((org.apache.axis.client.Call) soapCall).setSOAPService(soapService); - soapCall.removeAllParameters(); - soapCall.setTargetEndpointAddress( mobyService.getURL() ); - soapCall.setPortName( new QName( "http://biomoby.org/", mobyService.getName() + "PortType" ) ); - // soapCall.setOperationName(new QName("http://biomoby.org/", - // mobyService.getName())); - soapCall.setSOAPActionURI( "http://biomoby.org/#" + mobyService.getName() ); - return soapCall; - } - - /** - * Calls the invoke() method of the JAX-RPC Call interface. - */ - protected Element performSOAPRequest(Call soapCall, String mobyInputXML, StringBuffer contentsXMLOutput) - throws SOAPException { - // First, turn the input objects into a MOBY XML request - String[] mobyXMLInputData = new String[ 1 ]; - - // Setup - mobyXMLInputData[ 0 ] = mobyInputXML; - - if ( debug ) - debugPS.println( "returnType just before invoke call is " + soapCall.getReturnType() ); - Object returnedObject = null; - try { - returnedObject = soapCall.invoke( new QName( "http://biomoby.org/", mobyService.getName() ), - mobyXMLInputData ); - } - catch ( Exception e ) { - e.printStackTrace(); - // System.err.println("Input: "+mobyInputXML); - throw new SOAPException( "While invoking SOAP Call: " + e ); - } - - try { - if ( debug ) { - debugPS.println( "SOAP Response was:\n" ); - debugPS.println( soapCall.getResponseMessage().getSOAPPart().getEnvelope() ); - } - Element resultDom = ( ( MessageElement ) soapCall.getResponseMessage().getSOAPPart().getEnvelope() ).getAsDOM(); - return decodeSOAPMessage( resultDom, contentsXMLOutput, mobyInputXML ); - } - catch ( Exception e ) { - e.printStackTrace(); - throw new SOAPException( "Could not get SOAP response as DOM Element: " + e ); - } - - } - - public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML) throws SOAPException, - MobyException { - return decodeSOAPMessage( n, contentsXMLOutput, inputXML, false ); - } - - /** - * Isolates the MOBY Data from the SOAP message returned by the remote service host. - * - * @throws SOAPException if the MOBY payload cannot be found in the SOAP message - * @throws MobyException if the MOBY message is not well-formed XML - * - * @return The root element of the MOBY response DOM - */ - public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML, boolean async) - throws SOAPException, MobyException { - if ( n == null ) { - throw new SOAPException( "SOAP Message given to decode is null" ); - } - - NodeList node_list = null; - XPath responseElementXPath = null; - try { - if ( async ) { - responseElementXPath = new XPath( "//" + MobyPrefixResolver.WSRP_PREFIX + ":" - + AsyncClient.WSRP_MULTI_PROPERTY_TAG_NAME + "Response", null, mobyPrefixResolver, XPath.SELECT ); - } - else { - responseElementXPath = new XPath( "//" + MobyPrefixResolver.MOBY_TRANSPORT_PREFIX + ":" - + mobyService.getName() + "Response | //" + mobyService.getName() + "Response | " + "//" - + MobyPrefixResolver.MOBY_TRANSPORT_PREFIX + ":" + mobyService.getName() + " | //" - + mobyService.getName(), null, mobyPrefixResolver, XPath.SELECT ); - } - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select SOAP nodes due to exception " - + "while compiling XPath statement (code bug?):" + te ); - } - try { - node_list = runXPath( responseElementXPath, n ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select SOAP nodes due to exception " + "while executing XPath statement:" - + te ); - } - - if ( node_list == null || node_list.getLength() == 0 ) { - throw new SOAPException( "Could not find a response element in SOAP payload (service " - + mobyService.getName() + ")" ); - } - - if ( node_list.getLength() > 1 ) { - throw new SOAPException( "Found more than one response element in SOAP payload, " - + "unable to resolve ambiguity of the payload (service provider error?)" ); - } - - Node[] responseNodes = null; - if ( async ) { - Vector< Node > nodes = new Vector< Node >(); - NodeList resultNodeList = node_list.item( 0 ).getChildNodes(); - for ( int i = 0; resultNodeList != null && i < resultNodeList.getLength(); i++ ) { - if ( ! ( resultNodeList.item( i ) instanceof Element ) ) { - continue; - } - Element resultElement = ( Element ) resultNodeList.item( i ); - if ( resultElement.getLocalName().startsWith( AsyncClient.MOBY_RESULT_PROPERTY_PREFIX ) ) { - nodes.add( resultElement ); - } - } - responseNodes = nodes.toArray( new Node[ nodes.size() ] ); - } - else { - responseNodes = new Node[]{node_list.item( 0 )}; - } - - Element domRoot = null; // Where the result will be put - - for ( Node responseNode : responseNodes ) { - // Find base64 encoded elements in the SOAP message using XPath and - // replace them with the real decoded contents - node_list = null; - try { - node_list = runXPath( base64EncodedXPath, responseNode ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select base64 encoded SOAP nodes due to exception " - + "while executing XPath statement:" + te ); - } - if ( debug && node_list != null ) { - debugPS.println( "There were " + node_list.getLength() + " base64 encoded elements in the data" ); - } - - // Do decoding for each base64 part found - for ( int i = 0; node_list != null && i < node_list.getLength(); i++ ) { - org.w3c.dom.Node change = node_list.item( i ); - /* Make sure the text data is all put into one contiguous piece for decoding */ - change.normalize(); - - byte[] decodedBytes = org.apache.axis.encoding.Base64.decode( change.getFirstChild().getNodeValue() ); - String newText = new String( decodedBytes ); - if ( debug ) { - debugPS.println( "New decoded text is" + newText ); - } - - // Swap out this node for the decoded data - change.getParentNode().replaceChild( n.getOwnerDocument().createTextNode( new String( decodedBytes ) ), - change ); - } - - // Now see if there are any strings that need decoding - node_list = null; - try { - node_list = runXPath( stringEncodedXPath, responseNode ); - } - catch ( TransformerException te ) { - throw new SOAPException( "Cannot select string encoded SOAP nodes due to exception " - + "while executing XPath statement:" + te ); - } - - // Do concatenation for each plain string part found - for ( int i = 0; node_list != null && i < node_list.getLength(); i++ ) { - org.w3c.dom.Node change = node_list.item( i ); - /* Make sure the text data is all put into one contiguous piece for decoding */ - change.normalize(); - String plainString = ""; - int j = 0; - for ( NodeList children = change.getChildNodes(); children != null && j < children.getLength(); j++ ) { - Node child = children.item( j ); - if ( child instanceof CDATASection || child instanceof Text ) { - plainString += child.getNodeValue(); - if ( debug ) { - debugPS.println( "Plain string is now " + plainString ); - } - } - } - - // Swap out this node for the decoded data - change.getParentNode().replaceChild( n.getOwnerDocument().createCDATASection( plainString ), change ); - } - if ( debug && node_list != null ) { - debugPS.println( "There were " + node_list.getLength() - + " XML Schema string encoded elements in the data" ); - } - - // Parse the MOBY XML document payload - responseNode.normalize(); - NodeList children = responseNode.getChildNodes(); - if ( children == null ) { - throw new MobyException( "The MOBY payload has no contents at all" ); - } - if ( children.getLength() != 1 ) { - if ( debug ) { - debugPS.println( "Warning: MOBY Payload appears to have more than " - + "just text in it, skipping the non-text sections" ); - } - } - - Element predefinedDOM = null; // Choice of ripping DOM Element for moby payload out of SOAP DOM - String localResponseString = ""; // or storing raw XML strings, to be converted to a DOM later - for ( int j = 0; j < children.getLength(); j++ ) { - Node child = children.item( j ); - if ( child instanceof CDATASection || child instanceof Text ) { - // Unescape XML special characters in the string, so we can later on - // parse the payload as regular XML. - // Ignore whitespace-only node - if ( child.getNodeValue().matches( "^\\s+$" ) ) { - continue; - } - if ( debug ) { - debugPS.println( "Concatenating text in response " + child.getNodeValue() ); - } - localResponseString += child.getNodeValue();// .replaceAll("<", "<").replaceAll(">", - // ">").replaceAll("(&|F)", "&"); - } - if ( child instanceof Element && child.getLocalName().equals( MobyTags.MOBY ) ) { - debugPS.println( "Warning: The MOBY contents was found as raw XML inside the SOAP response!\n" - + "This is illegal according to the MOBY-API, please inform the service\n " - + " provider, as parsing such text may not be supported in the future" ); - localResponseString = null; - // Store the moby payload root element's DOM represntation, so we don't - // have to serialize it to the localResponseString and then parse it out - // again (that would be wasteful). - predefinedDOM = ( Element ) child; - break; - } - } - - if ( localResponseString != null ) { - if ( localResponseString.length() == 0 ) { - throw new MobyException( "The MOBY payload has no text contents at all" ); - } - if ( Character.isWhitespace( localResponseString.charAt( 0 ) ) ) { - localResponseString = localResponseString.trim(); - } - } - - // Check if the payload is an XML document. If not, try a last ditch effort - // by base64 decoding the contents. This is technically not allowable in the - // MOBY spec, but we are being lenient. - if ( localResponseString != null && !localResponseString.startsWith( "\n" + localResponseString; - debugPS.println( "Warning: The MOBY contents was missing an XML declaration, but it is " - + "required by the MOBY API, and may stop working in the future without it. Please " - + "contact the client's provider to correct this." ); - } - else { - String oldResponse = localResponseString; - localResponseString = new String( org.apache.axis.encoding.Base64.decode( localResponseString ) ); - if ( !localResponseString.startsWith( " entry : data.entrySet() ) { - String queryName = entry.getKey(); - MobyDataJob query = entry.getValue(); - - // Additionally, we check if they are MobyDataInstances below - Map< String, MobyPrimaryData > primaryParams = new HashMap< String, MobyPrimaryData >(); - Map< String, MobySecondaryData > secondaryParams = new HashMap< String, MobySecondaryData >(); - - // To store the primary input parameter name as given by the user, - // in case we need it later on for parameter renaming... - String primaryParamName = null; - - for ( Map.Entry< String, MobyDataInstance > subentry : query.entrySet() ) { - String name = subentry.getKey(); - MobyDataInstance param = subentry.getValue(); - if ( param == null ) { - throw new MobyException( "Query " + queryName + " contained a null input parameter (" + name + ")" ); - } - else if ( param instanceof MobyPrimaryData ) { - primaryParams.put( name, ( MobyPrimaryData ) param ); - primaryParamName = name; - } - else if ( param instanceof MobySecondaryData ) { - secondaryParams.put( name, ( MobySecondaryData ) param ); - } - else { - System.err.println( "Input parameter " + name + " (query " + queryName - + ") was not a MobyPrimaryData or MobySecondaryData " - + "as expected, but rather was of class " + param.getClass().getName() ); - } - } - - if ( inputs != null && inputs.length != primaryParams.size() ) { - throw new MobyException( "Service " + mobyService.getName() + " was provided " + primaryParams.size() - + " primary input parameter(s), but takes " + inputs.length + " (query " + queryName + ")" ); - } - if ( secondaries != null ) { - // If no secondaries provided, fill them in by default - if ( secondaries.length != 0 ) { - for ( MobySecondaryData secondary : secondaries ) { - if ( !secondaryParams.containsKey( secondary.getName() ) ) { - if ( debug ) { - System.err.println( "Setting default secondary param value for missing param " - + secondary ); - } - query.put( secondary.getName(), new MobyDataSecondaryInstance( secondary ) ); - } - } - } - if ( secondaries.length != secondaryParams.size() ) { - throw new MobyException( "Service " + mobyService.getName() + " was provided " - + secondaryParams.size() + " secondary input parameter(s), but takes " + secondaries.length - + " (query " + queryName + "). Extra secondary" + " parameters must have been specified" ); - } - } - - // If there was one anonymous input, assign the name automatically in - // the case the service requires it to be named. This is the only - // unambiguous case in which we can do this. - if ( inputs.length == 1 ) { - String serviceParamName = inputs[ 0 ].getName(); // name as req'd by the service - - // name isn't the same as required currently - if ( serviceParamName != null && serviceParamName.length() > 0 - && !serviceParamName.equals( primaryParamName ) ) { - // take out the old parameter - MobyPrimaryData theInputToRename = ( MobyPrimaryData ) query.remove( primaryParamName ); - - // Add in the same parameter, but with the appropriate name - query.put( serviceParamName, ( MobyDataInstance ) theInputToRename ); - } - } - } - - ByteArrayOutputStream mobyRequest = new ByteArrayOutputStream(); - try { - MobyDataUtils.toXMLDocument( mobyRequest, data ); - } - catch ( MobyException me ) { - throw me; - } - catch ( Exception e ) { - e.printStackTrace(); - throw new MobyException( "Could not create MOBY payload XML from input data: " + e ); - } - - if ( debug ) { - debugPS.println( "Input to MOBY Service is:" ); - debugPS.print( mobyRequest.toString() ); - } - - return mobyRequest.toString(); - } - - /** - * A method that sets up the execution environment for and runs a compiled XPath statement against a DOM node You - * should call releaseXPath when you're done with the results - * - * @return the list of Nodes that satisfy the XPath in this Node's context - */ - protected NodeList runXPath(XPath xpath, Node n) throws TransformerException { - NodeList result = null; - int dtm_node_handle = xpath_context.getDTMHandleFromNode( n ); - PrefixResolver node_prefix_resolver = new PrefixResolverDefault( n ); - XObject xobject = xpath.execute( xpath_context, n, node_prefix_resolver ); - if ( xobject instanceof XNodeSet ) { - result = ( ( XNodeSet ) xobject ).nodelist(); - } - else if ( debug && xobject != null ) { - debugPS.println( "Output of XPath was not a XNodeSet as expected, found " + xobject.getClass().getName() ); - debugPS.flush(); - } - return result; - } - - protected void releaseXPath(Node n) { - xpath_context.release( xpath_context.getDTM( xpath_context.getDTMHandleFromNode( n ) ), false ); - } -} +package org.biomoby.client; + +import java.io.*; +import java.util.*; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.rpc.Service; +import javax.xml.transform.TransformerException; + +import org.apache.axis.client.Call; +import org.apache.axis.message.MessageElement; +import org.apache.xml.utils.PrefixResolver; +import org.apache.xml.utils.PrefixResolverDefault; +import org.apache.xpath.XPath; +import org.apache.xpath.XPathContext; +import org.apache.xpath.objects.XNodeSet; +import org.apache.xpath.objects.XObject; + +import org.biomoby.shared.*; +import org.biomoby.shared.data.*; +import org.biomoby.shared.parser.MobyTags; // defined the Moby XML element names +import org.biomoby.w3c.addressing.EndpointReference; +import org.omg.lsae.notifications.AnalysisEvent; + +import org.w3c.dom.*; + +/** + * This class handles the WSDL transaction to request a response + * from a remote SOAP Web service that handles the + * MOBY format. It depends on + * having already retrieved the definition of the Web service via + * the MOBY central registry using the + * jMOBY API, + * and for now it uses the + * Apache + * Axis Web services framework, as well as Apache Xalan. There are code comments for the + * few lines that rely on Axis classes rather than the JAX-RPC interfaces. + * + * @author Paul Gordon gordonp at ucalgary.ca + */ +public class MobyRequest{ + + protected MobyService mobyService = null; + protected MobyContentInstance inputData = null; + protected MobyContentInstance outputData = null; + protected Central mobyCentral = null; + protected PrefixResolver mobyPrefixResolver = null; + + protected Hashtable wsdlCache = null; + protected String lastWsdlCacheKey = null; + protected DocumentBuilder docBuilder = null; + protected Service service = null; + + protected Class stringType; + protected static boolean debug = false; + protected PrintStream debugPS = System.err; + protected XPathContext xpath_context; + protected String responseString = null; + + private XPath stringEncodedXPath; + private XPath base64EncodedXPath; + private XPath simpleChildXPath; + private XPath collectionChildXPath; + private String user; + private String password; + + private int autoID = 0; + + // Used as invocation callback if MobyRequest is acting as a server, + // or is executing services as a client asynchronously + private Vector eventHandlers; + + /** + * Default constructor. You should have a Central instance around since you're going to + * be retrieving MobyServices to pass into here. Lets reuse it. + * + * @param central An instance of a Moby central object so we can make requests about object types, etc. + * @throws ParserConfigurationException if JAXP doesn't have any valid DOM-building XML parsers set up for use + */ + public MobyRequest(Central central) throws ParserConfigurationException{ + mobyCentral = central; + wsdlCache = new Hashtable(); + + eventHandlers = new Vector(); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + docBuilder = dbf.newDocumentBuilder(); + + try{ + stringType = Class.forName("java.lang.String"); + }catch(ClassNotFoundException classe){ + debugPS.println("WARNING: Something is very wrong, could not find Class definition of String: " + classe); + } + + xpath_context = new XPathContext(); + mobyPrefixResolver = new MobyPrefixResolver(); + + // Now compile the XPath statements that will be used fetch data from the server response + try{ + base64EncodedXPath = new XPath("//*[starts-with(substring-after(@"+ + MobyPrefixResolver.XSI1999_PREFIX+ + ":type, ':'), \"base64\") or starts-with(substring-after(@"+ + MobyPrefixResolver.XSI2001_PREFIX+ + ":type, ':'), \"base64\")]", null, + mobyPrefixResolver, XPath.SELECT); + stringEncodedXPath = new XPath("//*[substring-after(@"+ + MobyPrefixResolver.XSI1999_PREFIX+ + ":type, ':')=\"string\" or substring-after(@"+ + MobyPrefixResolver.XSI2001_PREFIX+ + ":type, ':')=\"string\"] | //"+ + MobyPrefixResolver.SOAP_ENC_PREFIX+":string", null, + mobyPrefixResolver, XPath.SELECT); + simpleChildXPath = new XPath("moby:Simple | Simple", null, + mobyPrefixResolver, XPath.SELECT); + collectionChildXPath = new XPath("moby:Collection | Collection", null, + mobyPrefixResolver, XPath.SELECT); + } + catch(TransformerException te){ + debugPS.println("Syntax error encountered while compiling XPath " + + "statements for internal use (code bug?): " + te); + } + setDebugMode(System.getProperty("moby.debug") != null); + } + + public void setAuthentication(String user, String password){ + this.user = user; + this.password = password; + } + + /** + * @param mode if true, debugging information is printed to the stream returned by getDebugOutputStream + */ + public void setDebugMode(boolean mode){ + debug = mode; + } + + /** + * Standard error is used unless this method is called. + * + * @param ps the OutputStream to which debugging information is sent. + * @throws IllegalArgumentException if the stream is null + */ + public void setDebugPrintStream(PrintStream ps) throws IllegalArgumentException{ + if(ps == null){ + throw new IllegalArgumentException("The OutputStream specified to MobyRequest was null"); + } + debugPS = ps; + } + + /** + * @return the instance of the class implementing Central that we are using + */ + public Central getCentralImpl(){ + return mobyCentral; + } + + /** + * @param mobyservice the MobyService that should be executed when invokeService is called + */ + public void setService(MobyService mobyservice){ + if(mobyservice == null){ + mobyService = null; + } + else if(mobyService == null || !mobyservice.equals(mobyService)){ + mobyService = mobyservice; + } + } + + /** + * @return the MobyService that will be executed when invokeService is called + */ + public MobyService getService(){ + return mobyService; + } + + /** + * @return the Raw MOBY XML response as a string + */ + public String getResponseXML(){ + return responseString; + } + + /** + * Sets the input data for the MOBY service request. The length of the input array, and the + * number of input parameters required by the service must be equal when invokeService() is called. + * This method strictly enforces that the input be of the appropriate type for the service. + * + * Note that there is no requirement to use MobyDataInstance.setXmlMode() before passing in + * data, this class will temporarily set the XML mode of the data when it is required. + * + * @throws IllegalArgumentException if the input does not fit the criteria of the service (e.g. wrong data type) + */ + public void setInput(MobyContentInstance data) throws MobyException{ + inputData = data; + } + + /** + * Takes the data in the array, with their current articleNames, as input for the service + */ + public void setInput(MobyDataInstance[] data) throws MobyException{ + MobyDataJob job = new MobyDataJob(); + for(MobyDataInstance param: data){ + job.put(param.getName(), param); + } + inputData = new MobyContentInstance(); + inputData.put(job); + } + + /** + * Convenience method to run services that take one argument. If the service + * requires the input to have a name, it will be automatically assigned. + */ + public void setInput(MobyDataInstance datum) throws MobyException{ + setInput(datum, ""); + } + + /** + * Convenience method to run services that take one named argument. + */ + public void setInput(MobyDataInstance datum, String paramName) throws MobyException{ + inputData = new MobyContentInstance(datum, paramName); + } + + /** + * @return the MobyService that will be executed when invokeService is called + */ + public MobyContentInstance getInput(){ + return inputData; + } + + /** + * Same functionality as setSecondaryInput(MobyDataSecondaryInstance[]) + */ + public void setSecondaryInput(Collection secondaryData) throws MobyException{ + setSecondaryInput(secondaryData.toArray(new MobyDataSecondaryInstance[secondaryData.size()])); + } + + /** + * This method will assign the provided secondary parameters to all primary input data currently + * in this object. This is covenient if you are running 100 seqs through BLAST and only want to set + * the parameters once. If you instead want to set secondary input differently for all primary inputs, you'll + * need to create a custom MobyContentInstance as input to setInput(). + * + * @throws MobyException if a parameter name is blank, or overrides a primary parameter + */ + public void setSecondaryInput(MobyDataSecondaryInstance[] secondaryData) throws MobyException{ + + Iterator queryNames = inputData.keySet().iterator(); + // For each query + while(queryNames.hasNext()){ + MobyDataJob queryParams = inputData.get(queryNames.next()); + // Set all the secondary params (overwrites any old ones) + for(int i = 0; i < secondaryData.length; i++){ + String secName = secondaryData[i].getName(); + if(secName == null || secName.length() == 0){ + throw new MobyException("A secondary parameter cannot have a blank name (array index " + i + ")"); + } + if(queryParams.containsKey(secName) && queryParams.get(secName) instanceof MobyPrimaryData){ + throw new MobyException("A secondary parameter cannot override an existing primary parameter " + + "with the same name (" + secName + ")"); + } + queryParams.put(secName, secondaryData[i]); + } + } + } + + /** + * @return a vector of MobyDataInstance[], each element of the vector is the collection of response objects for the correspondingly indexed input request. + * + * @throws MobyException if you try to get the results before calling InvokeService + */ + public MobyContentInstance getOutput() throws MobyException{ + if(outputData == null){ + throw new MobyException("Trying to access MOBY service results " + + "before the service is invoked"); + } + else{ + return outputData; + } + } + + /** + * The main method of the class. If all of the MOBY input objects + * are properly defined according to the Web service definition, + * a SOAP request will be sent to the remote server, and the method + * will return one or more MOBY objects (synchronous). + * Call this method after calling setService, and setInput. If you do not call + * setSecondaryInput, the default secondary parameter values will be used. + * + * @return the results of the remote Web service in response to the give input + * + * @throws MobyException i.e. there was something wrong with the input, output or remote service's logic + * @throws SOAPException i.e. there was a problem with the underlying transaction/transport layer + */ + public MobyContentInstance invokeService() throws Exception, MobyException, SOAPException, NoSuccessException{ + return mobyService.isAsynchronous() ? invokeService(inputData, new StringBuffer()) : invokeService(inputData, (StringBuffer) null); + } + + // Used internally for asynchronous thread calls that all need the XML data + // and can't rely on the answer from thread-insensitive getResponseXML() + private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML) + throws Exception, MobyException, SOAPException, NoSuccessException{ + return invokeService(inData, contentsXML, null, 0); + } + + private MobyContentInstance invokeService(MobyContentInstance inData, StringBuffer contentsXML, MobyRequestEventHandler handler, int requestId) + throws Exception, MobyException, SOAPException, NoSuccessException{ + + if(mobyService == null){ + throw new MobyException("Tried to invoke null service from MobyRequest (call setService first)"); + } + + Element mobyDOM = null; + if(mobyService.isAsynchronous()){ + // Async is "simpler", because it had to merge DOMs together into a single MobyContentInstance anyway + MobyContentInstance mci = performAsyncSOAPRequest(mobyService, inData, handler, requestId); + StringWriter writer = new StringWriter(); + MobyDataUtils.toXMLDocument(writer, mci); + contentsXML.append(writer.toString()); + return mci; + } + else{ + String mobyXML = convertMOBYDataToMOBYRequest(inData); + Call call = getServiceFromWSDL(); + if(user != null && password != null) { + call.setProperty( Call.USERNAME_PROPERTY, user ); + call.setProperty( Call.PASSWORD_PROPERTY, password ); + } + mobyDOM = performSOAPRequest(call, mobyXML, contentsXML); + // The following parses the DOM and extracts all the appropriate jMOBY objects to represent the XML in Java + return MobyDataUtils.fromXMLDocument(mobyDOM, mobyService.getServiceType().getRegistry()); + } + } + + protected MobyContentInstance performAsyncSOAPRequest(MobyService mservice, MobyContentInstance inData, + MobyRequestEventHandler handler, int requestId) + throws Exception{ + String mobyXML = convertMOBYDataToMOBYRequest(inData); + EndpointReference epr = AsyncClient.sendRequest(mservice, mobyXML); + + // Essentially cloning, so removing ids doesn't change the + // MobyContentInstance "data" (which we will use again later on) + MobyContentInstance finalContents = new MobyContentInstance(); + Set queryIDs = new HashSet(inData.keySet()); + try { + // Should add some timeout here... + while(!queryIDs.isEmpty()){ + // todo: make this setable + Thread.sleep(5000); + + AnalysisEvent[] events = + AsyncClient.poll(epr, queryIDs); + + Vector newDataAvailable = new Vector(); + for(AnalysisEvent event: events){ + if(event != null && event.isCompleted()){ + queryIDs.remove(event.getQueryId()); + newDataAvailable.add(event.getQueryId()); + } + } + + if(newDataAvailable.size() > 0){ + // Parse and merge the new data into the existing contents + InputStream resultStream = AsyncClient.getResultStream(epr, newDataAvailable); + Element mobyDOM = asyncSoapTextToMobyDOM(resultStream); + MobyContentInstance newResults = MobyDataUtils.fromXMLDocument(mobyDOM, mservice.getServiceType().getRegistry()); + // The merge + for(String jobid: newResults.keySet()){ + finalContents.put(jobid, newResults.get(jobid)); + } + + // Inform the handler that some data has been added to the response (for incremental display?) + if(handler != null){ + MobyRequestEvent mre = new MobyRequestEvent(finalContents, this, mservice, null, requestId); + StringWriter xmlWriter = new StringWriter(); + MobyDataUtils.toXMLDocument(xmlWriter, finalContents); + + mre.setContentsXML(xmlWriter.toString()); + if(!queryIDs.isEmpty()){ + // Send an update event only if we aren't finished yet. + // If we are finished, the client is going to get this event as the + // invocation thread finishes up (no need to double up). + handler.processEvent(mre); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + AsyncClient.destroy(epr); + throw new Exception("Exception occured while polling the service invocation: " + e); + } + + return finalContents; + } + + private Element asyncSoapTextToMobyDOM(InputStream inStream) throws Exception{ + Element soapDOM = null; + synchronized(docBuilder){ + soapDOM = docBuilder.parse(inStream).getDocumentElement(); + } + final boolean IS_ASYNC_SERVICE_CALL = true; + return decodeSOAPMessage(soapDOM, null, null, IS_ASYNC_SERVICE_CALL); + } + + /** + * Asynchronous call to invokeService. A callback to the passed-in handler will be made when + * the response is ready, or there is an exception. + * + * @return the id that the callback event will return from getID(), allowing a client to distinguish between multiple concurrent invocation callbacks + */ + public synchronized int invokeService(MobyRequestEventHandler handler){ + int id = autoID++; + + Thread t = new InvocationThread(this, inputData, handler, id); // see internal class definition below + t.start(); + + return id; + } + + // This is the class that asynchronously calls the service and does a callback to + // the handler specified in the invocation. + class InvocationThread extends Thread { + MobyContentInstance data; + MobyService mservice; + MobyRequest mobyRequest; + MobyRequestEventHandler handler; + int requestId; + + InvocationThread(MobyRequest mr, MobyContentInstance inData, MobyRequestEventHandler h, int id){ + data = inData; + mobyRequest = mr; + mservice = mobyRequest.getService(); + handler = h; + requestId = id; + + // Name the thread after the service being run, mostly for ease of debugging + setName(mservice.getName()+requestId); + } + + public void run() { + MobyRequestEvent requestEvent = new MobyRequestEvent(data, mobyRequest, mservice, null, requestId); + // Tell the handler we're starting the request, with the given data + handler.start(requestEvent); + + MobyRequestEvent responseEvent = null; + MobyContentInstance content = null; + StringBuffer contentsXML = new StringBuffer(); //to be filled in by the RPC call below + try{ + content = mobyRequest.invokeService(data, contentsXML, handler, requestId); //RPC call... + } + catch(Exception e){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, e, requestId); + } + catch(Error err){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, err, requestId); + } + if(responseEvent == null){ + responseEvent = new MobyRequestEvent(content, mobyRequest, mservice, null, requestId); + } + // We've got the raw XML laying around, so why not provide it unmolested to the callback? + responseEvent.setContentsXML(contentsXML.toString()); + handler.processEvent(responseEvent); + handler.stop(mobyRequest, requestId); + } + } + + public void addEventHandler(MobyRequestEventHandler h){ + eventHandlers.add(h); + } + + public void removeEventHandler(MobyRequestEventHandler h){ + eventHandlers.remove(h); + } + + public void sendResponse(MobyRequestEvent mre){ + // Not yet implemented, need to conform to some web.xml specification here... + } + + /** + * This method retrieves from Moby Central a copy of the WSDL document for the service + * (or uses an internally cached copy from a previous invocation), and sets the variables for the + * SOAP call appropriately so you can consequently call performSOAPRequest. + */ + protected Call getServiceFromWSDL() throws MobyException, NoSuccessException{ +// String wsdl = null; + +// // Since this is how we retrieve a service from Central, use the same values as the key to the hash +// String wsdlCacheKey = mobyService.getName() + "@" + mobyService.getAuthority(); + +// // This is the same call as last time, so we don't need to change the setup +// if(wsdlCacheKey.equals(lastWsdlCacheKey)){ +// return setCallFromWSDL((String) wsdlCache.get(wsdlCacheKey)); +// } +// // We haven't encountered this service yet +// else if(!wsdlCache.containsKey(wsdlCacheKey)){ +// wsdl = mobyCentral.getServiceWSDL(mobyService.getName(), mobyService.getAuthority()); +// wsdlCache.put(wsdlCacheKey, wsdl); +// } +// // We've dealt with this one before +// else{ +// wsdl = (String) wsdlCache.get(wsdlCacheKey); +// } + +// lastWsdlCacheKey = wsdlCacheKey; // Keep track of the last invocation + + // Get ready to do SOAP + return setCallFromWSDL(null); + } + + /** + * Creates the SOAP Call that will be invoked later. This should be based on the WSDL document + * and parameter information from the MobyService, but these are currently not up to snuff. + */ + protected Call setCallFromWSDL(String wsdl) throws MobyException, SOAPException{ + if(service == null){ + service = new org.apache.axis.client.Service(); // AXIS SPECIFIC This acts as a factory for Calls + } + + Call soapCall; + try{ + soapCall = (Call) service.createCall();//create a fresh Call each time + }catch(javax.xml.rpc.ServiceException se){ + throw new SOAPException("Could not instatiate call to SOAP Service: " + se); + } + + // Should initialize endpoint, etc. This call is AXIS SPECIFIC, otherwise you'll + // have to do the call's info setting manually. + //((org.apache.axis.client.Call) soapCall).setSOAPService(soapService); + soapCall.removeAllParameters(); + soapCall.setTargetEndpointAddress(mobyService.getURL()); + soapCall.setPortName(new QName("http://biomoby.org/", + mobyService.getName() + "PortType")); + //soapCall.setOperationName(new QName("http://biomoby.org/", + // mobyService.getName())); + soapCall.setSOAPActionURI("http://biomoby.org/#" + mobyService.getName()); + return soapCall; + } + + /** + * Calls the invoke() method of the JAX-RPC Call interface. + */ + protected Element performSOAPRequest(Call soapCall, String mobyInputXML, StringBuffer contentsXMLOutput) throws SOAPException{ + // First, turn the input objects into a MOBY XML request + String[] mobyXMLInputData = new String[1]; + + //Setup + mobyXMLInputData[0] = mobyInputXML; + + if(debug) + debugPS.println("returnType just before invoke call is " + soapCall.getReturnType()); + Object returnedObject = null; + try{ + returnedObject = soapCall.invoke(new QName("http://biomoby.org/", + mobyService.getName()), mobyXMLInputData); + } + catch(Exception e){ + e.printStackTrace(); + //System.err.println("Input: "+mobyInputXML); + throw new SOAPException("While invoking SOAP Call: " + e); + } + + try{ + if(debug){ + debugPS.println("SOAP Response was:\n"); + debugPS.println(soapCall.getResponseMessage().getSOAPPart().getEnvelope()); + } + Element resultDom = ((MessageElement) soapCall.getResponseMessage().getSOAPPart().getEnvelope()).getAsDOM(); + return decodeSOAPMessage(resultDom, contentsXMLOutput, mobyInputXML); + } catch(Exception e){ + e.printStackTrace(); + throw new SOAPException("Could not get SOAP response as DOM Element: "+ e); + } + + } + + public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML) + throws SOAPException, MobyException{ + return decodeSOAPMessage(n, contentsXMLOutput, inputXML, false); + } + + /** + * Isolates the MOBY Data from the SOAP message returned by the remote service host. + * + * @throws SOAPException if the MOBY payload cannot be found in the SOAP message + * @throws MobyException if the MOBY message is not well-formed XML + * + * @return The root element of the MOBY response DOM + */ + public Element decodeSOAPMessage(Element n, StringBuffer contentsXMLOutput, String inputXML, boolean async) + throws SOAPException, MobyException{ + if(n == null){ + throw new SOAPException("SOAP Message given to decode is null"); + } + + NodeList node_list = null; + XPath responseElementXPath = null; + try{ + if(async){ + responseElementXPath = new XPath("//"+MobyPrefixResolver.WSRP_PREFIX + + ":"+AsyncClient.WSRP_MULTI_PROPERTY_TAG_NAME+"Response", + null, mobyPrefixResolver, XPath.SELECT); + } + else{ + responseElementXPath = new XPath("//"+ MobyPrefixResolver.MOBY_TRANSPORT_PREFIX+ + ":"+mobyService.getName()+"Response | //" + + mobyService.getName()+"Response | " + + "//"+ MobyPrefixResolver.MOBY_TRANSPORT_PREFIX+ + ":"+mobyService.getName() + " | //" + + mobyService.getName(), + null, mobyPrefixResolver, XPath.SELECT); + } + }catch(TransformerException te){ + throw new SOAPException("Cannot select SOAP nodes due to exception "+ + "while compiling XPath statement (code bug?):" +te); + } + try{ + node_list = runXPath(responseElementXPath, n); + }catch(TransformerException te){ + throw new SOAPException("Cannot select SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + + if(node_list == null || node_list.getLength() == 0){ + throw new SOAPException("Could not find a response element in SOAP payload (service " + + mobyService.getName() + ")"); + } + + if(node_list.getLength() > 1){ + throw new SOAPException("Found more than one response element in SOAP payload, " + + "unable to resolve ambiguity of the payload (service provider error?)"); + } + + Node[] responseNodes = null; + if(async){ + Vector nodes = new Vector(); + NodeList resultNodeList = node_list.item(0).getChildNodes(); + for(int i = 0; resultNodeList != null && i < resultNodeList.getLength(); i++){ + if(!(resultNodeList.item(i) instanceof Element)){ + continue; + } + Element resultElement = (Element) resultNodeList.item(i); + if(resultElement.getLocalName().startsWith(AsyncClient.MOBY_RESULT_PROPERTY_PREFIX)){ + nodes.add(resultElement); + } + } + responseNodes = nodes.toArray(new Node[nodes.size()]); + } + else{ + responseNodes = new Node[]{node_list.item(0)}; + } + + Element domRoot = null; // Where the result will be put + + for(Node responseNode: responseNodes){ + // Find base64 encoded elements in the SOAP message using XPath and + // replace them with the real decoded contents + node_list = null; + try{ + node_list = runXPath(base64EncodedXPath, responseNode); + } + catch(TransformerException te){ + throw new SOAPException("Cannot select base64 encoded SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + if(debug && node_list != null){ + debugPS.println("There were " + node_list.getLength() + + " base64 encoded elements in the data"); + } + + // Do decoding for each base64 part found + for(int i = 0; node_list != null && i < node_list.getLength(); i++){ + org.w3c.dom.Node change = node_list.item(i); + /* Make sure the text data is all put into one contiguous piece for decoding*/ + change.normalize(); + + byte[] decodedBytes = org.apache.axis.encoding.Base64.decode(change.getFirstChild().getNodeValue()); + String newText = new String(decodedBytes); + if(debug){ + debugPS.println("New decoded text is" + newText); + } + + // Swap out this node for the decoded data + change.getParentNode().replaceChild(n.getOwnerDocument().createTextNode(new String(decodedBytes)), + change); + } + + // Now see if there are any strings that need decoding + node_list = null; + try{ + node_list = runXPath(stringEncodedXPath, responseNode); + } + catch(TransformerException te){ + throw new SOAPException("Cannot select string encoded SOAP nodes due to exception "+ + "while executing XPath statement:" +te); + } + + // Do concatenation for each plain string part found + for(int i = 0; node_list != null && i < node_list.getLength(); i++){ + org.w3c.dom.Node change = node_list.item(i); + /* Make sure the text data is all put into one contiguous piece for decoding*/ + change.normalize(); + String plainString = ""; + int j = 0; + for(NodeList children = change.getChildNodes(); + children != null && j < children.getLength(); + j++){ + Node child = children.item(j); + if(child instanceof CDATASection || child instanceof Text){ + plainString += child.getNodeValue(); + if(debug){ + debugPS.println("Plain string is now " + plainString); + } + } + } + + // Swap out this node for the decoded data + change.getParentNode().replaceChild(n.getOwnerDocument().createCDATASection(plainString), change); + } + if(debug && node_list != null){ + debugPS.println("There were " + node_list.getLength() + + " XML Schema string encoded elements in the data"); + } + + // Parse the MOBY XML document payload + responseNode.normalize(); + NodeList children = responseNode.getChildNodes(); + if(children == null){ + throw new MobyException("The MOBY payload has no contents at all"); + } + if(children.getLength() != 1){ + if(debug){ + debugPS.println("Warning: MOBY Payload appears to have more than " + + "just text in it, skipping the non-text sections"); + } + } + + Element predefinedDOM = null; // Choice of ripping DOM Element for moby payload out of SOAP DOM + String localResponseString = ""; // or storing raw XML strings, to be converted to a DOM later + for(int j = 0; j < children.getLength(); j++){ + Node child = children.item(j); + if(child instanceof CDATASection || child instanceof Text){ + // Unescape XML special characters in the string, so we can later on + // parse the payload as regular XML. + // Ignore whitespace-only node + if(child.getNodeValue().matches("^\\s+$")){ + continue; + } + if(debug){ + debugPS.println("Concatenating text in response " + child.getNodeValue()); + } + localResponseString += child.getNodeValue();//.replaceAll("<", "<").replaceAll(">", ">").replaceAll("(&|F)", "&"); + } + if(child instanceof Element && child.getLocalName().equals(MobyTags.MOBY)){ + debugPS.println("Warning: The MOBY contents was found as raw XML inside the SOAP response!\n" + + "This is illegal according to the MOBY-API, please inform the service\n " + + " provider, as parsing such text may not be supported in the future"); + localResponseString = null; + // Store the moby payload root element's DOM represntation, so we don't + // have to serialize it to the localResponseString and then parse it out + // again (that would be wasteful). + predefinedDOM = (Element) child; + break; + } + } + + if(localResponseString != null){ + if(localResponseString.length() == 0){ + throw new MobyException("The MOBY payload has no text contents at all"); + } + if(Character.isWhitespace(localResponseString.charAt(0))){ + localResponseString = localResponseString.trim(); + } + } + + // Check if the payload is an XML document. If not, try a last ditch effort + // by base64 decoding the contents. This is technically not allowable in the + // MOBY spec, but we are being lenient. + if(localResponseString != null && !localResponseString.startsWith("\n"+localResponseString; + debugPS.println("Warning: The MOBY contents was missing an XML declaration, but it is " + + "required by the MOBY API, and may stop working in the future without it. Please " + + "contact the client's provider to correct this."); + } + else{ + String oldResponse = localResponseString; + localResponseString = new String(org.apache.axis.encoding.Base64.decode(localResponseString)); + if(!localResponseString.startsWith(" entry: data.entrySet()){ + String queryName = entry.getKey(); + MobyDataJob query = entry.getValue(); + + // Additionally, we check if they are MobyDataInstances below + Map primaryParams = new HashMap(); + Map secondaryParams = new HashMap(); + + // To store the primary input parameter name as given by the user, + // in case we need it later on for parameter renaming... + String primaryParamName = null; + + for(Map.Entry subentry: query.entrySet()){ + String name = subentry.getKey(); + MobyDataInstance param = subentry.getValue(); + if(param == null){ + throw new MobyException("Query " + queryName + + " contained a null input parameter (" + name + ")"); + } + else if(param instanceof MobyPrimaryData){ + primaryParams.put(name, (MobyPrimaryData) param); + primaryParamName = name; + } + else if(param instanceof MobySecondaryData){ + secondaryParams.put(name, (MobySecondaryData) param); + } + else{ + System.err.println("Input parameter " + name + " (query " + queryName + + ") was not a MobyPrimaryData or MobySecondaryData " + + "as expected, but rather was of class " + param.getClass().getName()); + } + } + + if(inputs != null && inputs.length != primaryParams.size()){ + throw new MobyException("Service " + mobyService.getName() + " was provided " + + primaryParams.size() + + " primary input parameter(s), but takes " + inputs.length + + " (query " + queryName + ")"); + } + if(secondaries != null){ + // If no secondaries provided, fill them in by default + if(secondaries.length != 0){ + for(MobySecondaryData secondary: secondaries){ + if(!secondaryParams.containsKey(secondary.getName())){ + if(debug){ + System.err.println("Setting default secondary param value for missing param " + secondary); + } + query.put(secondary.getName(), new MobyDataSecondaryInstance(secondary)); + } + } + } + if(secondaries.length != secondaryParams.size()){ + throw new MobyException("Service " + mobyService.getName() + " was provided " + + secondaryParams.size() + + " secondary input parameter(s), but takes " + secondaries.length + + " (query " + queryName + "). Extra secondary" + + " parameters must have been specified"); + } + } + + // If there was one anonymous input, assign the name automatically in + // the case the service requires it to be named. This is the only + // unambiguous case in which we can do this. + if(inputs.length == 1){ + String serviceParamName = inputs[0].getName(); // name as req'd by the service + + // name isn't the same as required currently + if(serviceParamName != null && serviceParamName.length() > 0 && + !serviceParamName.equals(primaryParamName)){ + // take out the old parameter + MobyPrimaryData theInputToRename = (MobyPrimaryData) query.remove(primaryParamName); + + // Add in the same parameter, but with the appropriate name + query.put(serviceParamName, (MobyDataInstance) theInputToRename); + } + } + } + + ByteArrayOutputStream mobyRequest = new ByteArrayOutputStream(); + try{ + MobyDataUtils.toXMLDocument(mobyRequest, data); + } + catch(MobyException me){ + throw me; + } + catch(Exception e){ + e.printStackTrace(); + throw new MobyException("Could not create MOBY payload XML from input data: " +e); + } + + if(debug){ + debugPS.println("Input to MOBY Service is:"); + debugPS.print(mobyRequest.toString()); + } + + return mobyRequest.toString(); + } + + /** + * A method that sets up the execution environment for and runs a compiled XPath statement against a DOM node + * You should call releaseXPath when you're done with the results + * @return the list of Nodes that satisfy the XPath in this Node's context + */ + protected NodeList runXPath(XPath xpath, Node n) throws TransformerException{ + NodeList result = null; + int dtm_node_handle = xpath_context.getDTMHandleFromNode(n); + PrefixResolver node_prefix_resolver = new PrefixResolverDefault(n); + XObject xobject = xpath.execute(xpath_context, n, node_prefix_resolver); + if(xobject instanceof XNodeSet){ + result = ((XNodeSet) xobject).nodelist(); + } + else if(debug && xobject != null){ + debugPS.println("Output of XPath was not a XNodeSet as expected, found " + xobject.getClass().getName()); + debugPS.flush(); + } + return result; + } + + protected void releaseXPath(Node n){ + xpath_context.release(xpath_context.getDTM(xpath_context.getDTMHandleFromNode(n)), false); + } +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java 2008/11/26 08:53:43 1.13 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/BaseClient.java 2008/12/03 15:21:13 1.14 @@ -1,429 +1,487 @@ -// BaseClient.java -// -// Created: August 2005 -// -// This file is a component of the BioMoby project. -// Copyright Martin Senger (martin.senger at gmail.com). -// - -package org.biomoby.client; - -import java.io.StringReader; -import java.net.MalformedURLException; -import java.net.URL; - -import org.apache.axis.client.Call; -import org.apache.commons.lang.StringUtils; -import org.biomoby.shared.Central; -import org.biomoby.shared.MobyException; -import org.biomoby.shared.MobyService; -import org.biomoby.shared.parser.JDOMUtils; -import org.biomoby.shared.parser.MobyJob; -import org.biomoby.shared.parser.MobyPackage; -import org.biomoby.shared.parser.MobyTags; -import org.biomoby.shared.parser.ServiceException; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.input.SAXBuilder; -import org.tulsoft.shared.GException; -import org.tulsoft.tools.soap.axis.AxisCall; - -/** - * This is a base class for Biomoby clients. It takes care about converting user input into Biomoby XML, sending it in a - * SOAP message to a Biomoby service, waiting for the response and parsing it from Biomoby XML. It also divides requests - * and responses into so-called jobs - each of them corresponds to a Biomoby query (a Biomoby single network - * request may contain more queries/jobs). - *

      - * - * Any client can override various methods - but the ones she/he must override in a subclass are those - * telling what service to call ({@link #getServiceLocator}), what data to put in a request ({@link #fillRequest(MobyJob,MobyPackage) fillRequest}), - * and what to do with a response ({@link #useResponse(MobyJob,MobyPackage) useResponse}. - *

      - * - * @author Martin Senger - * @version $Id$ - */ - -abstract public class BaseClient { - private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( BaseClient.class ); - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - static protected boolean notEmpty(String value) { - return StringUtils.isNotBlank( value ); - } - static protected boolean isEmpty(String value) { - return StringUtils.isBlank( value ); - } - - /******************************************************************************************************************* - * The main method that packs input data, invokes a BioMoby service and uses its response. Use this method if the - * input data should have just one job (which is a usual case) - otherwise use method {@link #process(int)}. - *

      - * - * @throws MobyException if (a) a sub-class throws it during the filling data or using response, or (b) a Biomoby - * service invocation fails - ******************************************************************************************************************/ - public void process() throws MobyException { - process( 1 ); - } - - /******************************************************************************************************************* - * The main method that packs input data, invokes a BioMoby service and uses its response. The input data may - * consist from more than one job (query) - the 'jobCount' is a suggestion how many jobs will be included, but this - * can be changed by the implementing sub-class. - *

      - * - * Usually a client developer does not need to overwrite this method. She or he makes the real input data filling in - * the {@link #fillRequest} method, and uses the response in the {@link #useResponse} method. - *

      - * - * @throws MobyException if (a) a sub-class throws it during the filling data or using response, or (b) a Biomoby - * service invocation fails - ******************************************************************************************************************/ - public void process(int jobCount) throws MobyException { - - String xmlResponse = null; - - // input: raw-level processing - String xmlInput = fillRequest(); - if ( xmlInput != null ) { - if ( ( xmlInput = interceptRequest( xmlInput ) ) == null ) - return; - } - - // input: usual processing (i.e. collect XML in iterations) - else { - MobyPackage mobyInput = new MobyPackage(); - if ( !fillRequest( mobyInput, jobCount ) ) - return; - xmlInput = mobyInput.toXML(); - if ( ( xmlInput = interceptRequest( xmlInput ) ) == null ) - return; - } - - // calling service - xmlResponse = callRemoteService( xmlInput ); - - // output: raw-level processing - if ( !useResponse( xmlResponse ) ) - return; - - // output: usual processing (again by iterations) - MobyPackage mobyResponse = MobyPackage.createFromXML( xmlResponse ); - useResponse( mobyResponse ); - } - - public String interceptRequest(String xmlInput) throws MobyException { - return xmlInput; - } - - /******************************************************************************************************************* - * Create raw XML input. Override this method if you have already an input XML, or you want to create it yourself. - *

      - * - * @return a full XML input for a Biomoby service (in this case no other fillRequest methods will - * called); return null if no XML was created and a usual process to gather it will be used - * - * @throws MobyException if an XML cannot be created - ******************************************************************************************************************/ - public String fillRequest() throws MobyException { - return null; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected String filterMobyResponseType(Object result) throws MobyException { - if ( result instanceof String ) - return ( String ) result; - else if ( result instanceof byte[] ) - return new String( ( byte[] ) result ); - else - throw new MobyException( - "The Biomoby data should be sent/received either as type String or base64/byte[]. " - + "But they are of type '" + result.getClass().getName() + "'." ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected String callBiomobyService(MobyServiceLocator locator, String xmlInput) throws MobyException { - - MobyService service = locator.getService(); - String serviceName = service.getName(); - boolean asBytes = locator.isAsBytes(); - String serviceEndpoint = service.getURL(); - int timeout = locator.getSuggestedTimeout(); - - try { - URL target = new URL( serviceEndpoint ); - AxisCall call = new AxisCall( target, timeout ); - // to allow service calls which need authentication - setAuthentication( call.getCall() ); - call.getCall().setSOAPActionURI( MobyService.BIOMOBY_SERVICE_URI + "#" + serviceName ); - - return filterMobyResponseType( call.doCall( MobyService.BIOMOBY_SERVICE_URI, serviceName, - new Object[]{sendingFilter( xmlInput, asBytes )} ) ); - } - catch ( MalformedURLException e ) { - throw new MobyException( "Service endpoint '" + serviceEndpoint + "' is not a valid URL." ); - } - catch ( GException e ) { - throw new MobyException( e.getMessage(), e ); - } - } - - /** - * Sets the authentication for the call. The default implementation does not do anything ! - * - * @param call - */ - protected void setAuthentication(Call call) { - return; - } - - // - protected Object sendingFilter(String input, boolean asBytes) { - if ( asBytes ) { - log.debug( "Data sent as a byte array" ); - return input.getBytes(); - } - else { - return input; - } - } - - /******************************************************************************************************************* - * Call a SOAP-based BioMoby service. In order to find what service to call and what are its characteristics (such - * as its endpoint) it will call method {@link #getServiceLocator} that should be implemented by a sub-class. - *

      - * - * Once it has the service locator, this class does one of the following, in this order: - *

        - * - *
      • The locator must contain at least a service name. If it does not, an exception is raised. - * - *
      • If the locator contains a service endpoint, a call is made to this endpoint, using also the service name as - * a method name. - * - *
      • If the locator has a registry endpoint, an enquiry to the registry is made to find an endpoint of a service - * corresponding with the given service name. Once found, the service is called. - * - *
      • The same as the previous one but using a default registry. - * - * @param xmlInput data will be sent to the called Biomoby service - * - * @return service response (still in XML) - * - * @throws MobyException (a) if service call (or a call to registry; for example because the registry does not know - * given service) fails, or (b) if the used {@link MobyServiceLocator} does not contain a service name. - * - ******************************************************************************************************************/ - public String callRemoteService(String xmlInput) throws MobyException { - - // 1) service name is a must - MobyServiceLocator locator = getServiceLocator(); - MobyService service = locator.getService(); - if ( service == null ) - throw new MobyException( "MobyService locator returned an empty service object.\n" - + "I do not know what service to call..." ); - String serviceName = service.getName(); - if ( isEmpty( serviceName ) || MobyService.DUMMY_NAME.equals( serviceName ) ) - throw new MobyException( "MobyService locator returned an empty service name.\n" - + "I do not know what service to call..." ); - - // 2) try service endpoint - String serviceEndpoint = service.getURL(); - if ( notEmpty( serviceEndpoint ) ) - return callBiomobyService( locator, xmlInput ); - - // 3) find service endpoint in a Biomoby registry - Central worker = new CentralImpl( locator.getRegistryEndpoint(), locator.getRegistryNamespace() ); - MobyService[] services = worker.findService( service ); - if ( services == null || services.length == 0 ) - throw new MobyException( "Service " + service.toShortString() + " is not known in Biomoby registry: \n" - + "\t" + worker.getRegistryEndpoint() + "\n" + "\t" + worker.getRegistryNamespace() ); - // ...and call the service - serviceEndpoint = services[ 0 ].getURL(); - if ( notEmpty( serviceEndpoint ) ) { - service.setURL( serviceEndpoint ); - return callBiomobyService( locator, xmlInput ); - } - - // what else can I do? - throw new MobyException( "Registry has not returned any URL for service " + service.toShortString() ); - } - - /******************************************************************************************************************* - * Fill the whole 'mobyInput' - put there any number of jobs (queries) as you wish (you do not need to follow the - * 'jobCount' hint suggesting how many jobs should be put there). - *

        - * - * Usually there is not need to overwrite this method. It serves as an inter-mediator between the main - * {@link #process} method and the individual request fillings (done by a sub-class in method - * {@link #fillRequest(MobyJob,MobyPackage)}). - *

        - * - * @return false if you wish to cancel whole request (nothing will be sent to a Biomoby service); otherwise return - * true. - * - * @param mobyInput is an empty shell that you are supposed to fill with the input data for a Biomoby service - * execution - * - * @param jobCount is only a suggestion how many requests/job should be created (it comes from the {@link #process} - * method) - but it does not need to be obeyed - * - ******************************************************************************************************************/ - public boolean fillRequest(MobyPackage mobyInput, int jobCount) throws MobyException { - - if ( jobCount < 0 ) - jobCount = 0; - for ( int i = 0; i < jobCount; i++ ) { - MobyJob request = new MobyJob( "job_" + i ); - if ( !fillRequest( request, mobyInput ) ) - break; - mobyInput.addJob( request ); - } - return ( mobyInput.size() > 0 ); - } - - /******************************************************************************************************************* - * A raw-level processing. Use it if you need access to raw XML coming from a service. - *

        - * - * @param xmlResponse is a raw XML response returned from a BioMoby service - * - * @return false if the response should be considered fully processed (in this case no other 'useResponse' will be - * called); true indicates that normal processing of the response will follow; by default, this class (BaseClient) - * returns true - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'mobyResponse' is broken - ******************************************************************************************************************/ - public boolean useResponse(String xmlResponse) throws MobyException { - return true; - } - - /******************************************************************************************************************* - * A high-level processing. Use it if you need access to all jobs (queries) - that returned from a service - in the - * same time. Otherwise use the processing on the job level (method {@link #useResponse(MobyJob,MobyPackage)}. - *

        - * - * @param mobyResponse is a full response returned from a BioMoby service - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'mobyResponse' is broken - ******************************************************************************************************************/ - public void useResponse(MobyPackage mobyResponse) throws MobyException { - - // iterate over all input jobs - for ( int i = 0; i < mobyResponse.size(); i++ ) { - if ( !useResponse( mobyResponse.getJob( i ), mobyResponse ) ) - return; - } - } - - /******************************************************************************************************************* - * Extracts errors from a raw service response. It is iseful when one does not want to create a whole - * MobyPackage from a response, but just find whether a response is good or bad. - *

        - * - * @param xmlResponse is a full response returned from a BioMoby service - * - * @return a slightly formatted list of exceptions (of severity error) extracted from the response; or - * null if there are no errors there - ******************************************************************************************************************/ - public String errorsInResponse(String xmlResponse) { - try { - StringBuffer buf = new StringBuffer(); - SAXBuilder builder = new SAXBuilder(); - Document doc = builder.build( new StringReader( xmlResponse ) ); - Element root = doc.getRootElement(); - Element mobyContent = JDOMUtils.getChild( root, MobyTags.MOBYCONTENT ); - Element serviceNotes = JDOMUtils.getChild( mobyContent, MobyTags.SERVICENOTES ); - ServiceException[] exceptions = ServiceException.extractExceptions( serviceNotes ); - for ( int i = 0; i < exceptions.length; i++ ) { - if ( exceptions[ i ].getSeverity() != ServiceException.ERROR ) - continue; - if ( buf.length() > 0 ) - buf.append( "\n" ); - buf.append( exceptions[ i ].getErrorCodeAsString() ); - buf.append( ": " ); - buf.append( exceptions[ i ].getMessage() ); - } - return ( buf.length() == 0 ? null : new String( buf ) ); - - } - catch ( Exception e ) { - return e.toString(); - } - } - - // - // Abstract methods - // - - /******************************************************************************************************************* - * Return characteristics of a BioMoby service that will be called, and that reveal where to find such service. - *

        - * - * @see #callRemoteService - * - * @return an object defining a location of a BioMoby service - * @throws MobyException if service locator cannot be returned/created (e.g. because there is not enough information - * about what service to call) - ******************************************************************************************************************/ - abstract public MobyServiceLocator getServiceLocator() throws MobyException; - - /******************************************************************************************************************* - * Crate data (fill them into 'request') for one Moby job (query). The request will be sent within given - * 'inputContext' - but it is not yet there (because you may wish not to put it there - see the return value), and - * it is not the task of this method to put it there (just fill the 'request'). - *

        - * - * This is a method that should be implemented by a client developer, and it is the place where the client's - * business logic sits. - *

        - * - * @return true if this request should be included into the input data (package) that will be sent to a biomoby - * service; or return false if you do not wish to create any more requests for this particular package (also - * this 'request' will not be used) - * - * @param request is an object that you are supposed to fill with input data for one service invocation; it already - * has a name (so called 'query id' in the BioMoby speak) but you are free to change it - * - * @param inputContext is an envelope where all requests will be stored and sent to a Biomoby service; you do not - * need to do anything with it here unless you wish; note that all already created requests are there, - * but not the one you are just creating in this method - * - * @throws MobyException if you need so (from whatever reason in your business logic); if thrown then nothing will - * be sent to a Biomoby service - * - ******************************************************************************************************************/ - abstract public boolean fillRequest(MobyJob request, MobyPackage inputContext) throws MobyException; - - /******************************************************************************************************************* - * Process a single job returned from a BioMoby service. - *

        - * - * This is a method that should be implemented by a client developer, and it is the place where the client's - * business logic using the response sits. - *

        - * - * @param response is an object that you are supposed to use - * - * @param responseContext is an envelope where the full response (all its jobs) is located; you do not need to do - * anything with it here unless you wish (e.g. it gives you knowledge about how many jobs are in the full - * response, or it gives you access to the so-called 'service notes') - * - * @return false if you do not wish to get any more responses/jobs; otherwise return true - * - * @throws MobyException if you are not satisfied with a response data, or from whatever reasons; it also throws - * this exception if the 'response' is broken - * - ******************************************************************************************************************/ - abstract public boolean useResponse(MobyJob response, MobyPackage responseContext) throws MobyException; - -} +// BaseClient.java +// +// Created: August 2005 +// +// This file is a component of the BioMoby project. +// Copyright Martin Senger (martin.senger at gmail.com). +// + +package org.biomoby.client; + +import org.biomoby.shared.MobyException; +import org.biomoby.shared.MobyService; +import org.biomoby.shared.parser.JDOMUtils; +import org.biomoby.shared.Central; +import org.biomoby.client.CentralImpl; +import org.biomoby.shared.parser.MobyPackage; +import org.biomoby.shared.parser.MobyJob; +import org.biomoby.shared.parser.ServiceException; +import org.biomoby.shared.parser.MobyTags; + +import org.tulsoft.tools.soap.axis.AxisCall; +import org.tulsoft.shared.GException; + +import org.apache.axis.client.Call; +import org.apache.commons.lang.StringUtils; + +import org.jdom.input.SAXBuilder; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.Namespace; + +import java.net.URL; +import java.net.MalformedURLException; +import java.io.StringReader; + +/** + * This is a base class for Biomoby clients. It takes care about + * converting user input into Biomoby XML, sending it in a SOAP + * message to a Biomoby service, waiting for the response and parsing + * it from Biomoby XML. It also divides requests and responses into + * so-called jobs - each of them corresponds to a Biomoby + * query (a Biomoby single network request may contain more + * queries/jobs).

        + * + * Any client can override various methods - but the ones she/he + * must override in a subclass are those telling what service + * to call ({@link #getServiceLocator}), what data to put in a request + * ({@link #fillRequest(MobyJob,MobyPackage) fillRequest}), and what + * to do with a response ({@link #useResponse(MobyJob,MobyPackage) + * useResponse}.

        + * + * @author Martin Senger + * @version $Id$ + */ + +abstract public class BaseClient { + + private static org.apache.commons.logging.Log log = + org.apache.commons.logging.LogFactory.getLog (BaseClient.class); + + /************************************************************************** + * + *************************************************************************/ + static protected boolean notEmpty (String value) { + return StringUtils.isNotBlank (value); + } + static protected boolean isEmpty (String value) { + return StringUtils.isBlank (value); + } + + /************************************************************************** + * The main method that packs input data, invokes a BioMoby + * service and uses its response. Use this method if the input + * data should have just one job (which is a usual case) - + * otherwise use method {@link #process(int)}.

        + * + * @throws MobyException if (a) a sub-class throws it during the + * filling data or using response, or (b) a Biomoby service + * invocation fails + *************************************************************************/ + public void process() + throws MobyException { + process (1); + } + + /************************************************************************** + * The main method that packs input data, invokes a BioMoby + * service and uses its response. The input data may consist from + * more than one job (query) - the 'jobCount' is a suggestion how + * many jobs will be included, but this can be changed by the + * implementing sub-class.

        + * + * Usually a client developer does not need to overwrite this + * method. She or he makes the real input data filling in the + * {@link #fillRequest} method, and uses the response in the + * {@link #useResponse} method.

        + * + * @throws MobyException if (a) a sub-class throws it during the + * filling data or using response, or (b) a Biomoby service + * invocation fails + *************************************************************************/ + public void process (int jobCount) + throws MobyException { + + String xmlResponse = null; + + // input: raw-level processing + String xmlInput = fillRequest(); + if (xmlInput != null) { + if ( (xmlInput = interceptRequest (xmlInput)) == null ) + return; + } + + // input: usual processing (i.e. collect XML in iterations) + else { + MobyPackage mobyInput = new MobyPackage(); + if (! fillRequest (mobyInput, jobCount)) return; + xmlInput = mobyInput.toXML(); + if ( (xmlInput = interceptRequest (xmlInput)) == null ) + return; + } + + // calling service + xmlResponse = callRemoteService (xmlInput); + + // output: raw-level processing + if (! useResponse (xmlResponse)) return; + + // output: usual processing (again by iterations) + MobyPackage mobyResponse = MobyPackage.createFromXML (xmlResponse); + useResponse (mobyResponse); + } + + public String interceptRequest (String xmlInput) + throws MobyException { + return xmlInput; + } + + /************************************************************************** + * Create raw XML input. Override this method if you have already + * an input XML, or you want to create it yourself.

        + * + * @return a full XML input for a Biomoby service (in this case no + * other fillRequest methods will called); return null if + * no XML was created and a usual process to gather it will be used + * + * @throws MobyException if an XML cannot be created + *************************************************************************/ + public String fillRequest() + throws MobyException { + return null; + } + + /************************************************************************** + * + *************************************************************************/ + protected String filterMobyResponseType (Object result) + throws MobyException { + if (result instanceof String) + return (String)result; + else if (result instanceof byte[]) + return new String ((byte[])result); + else + throw new MobyException + ("The Biomoby data should be sent/received either as type String or base64/byte[]. " + + "But they are of type '" + result.getClass().getName() + "'."); + } + + /************************************************************************** + * + *************************************************************************/ + protected String callBiomobyService (MobyServiceLocator locator, + String xmlInput) + throws MobyException { + + + MobyService service = locator.getService(); + String serviceName = service.getName(); + boolean asBytes = locator.isAsBytes(); + String serviceEndpoint = service.getURL(); + int timeout = locator.getSuggestedTimeout(); + + try { + URL target = new URL (serviceEndpoint); + AxisCall call = new AxisCall (target, timeout); + // if the locator has authentication information. + if(locator.hasAuthentication()) { + call.getCall().setProperty( Call.USERNAME_PROPERTY, locator.getUser() ); + call.getCall().setProperty( Call.PASSWORD_PROPERTY, locator.getPassword() ); + } + call.getCall().setSOAPActionURI (MobyService.BIOMOBY_SERVICE_URI + "#" + serviceName); + return filterMobyResponseType + (call.doCall (MobyService.BIOMOBY_SERVICE_URI, + serviceName, + new Object[] { sendingFilter (xmlInput, asBytes) })); + } catch (MalformedURLException e) { + throw new MobyException ("Service endpoint '" + serviceEndpoint + + "' is not a valid URL."); + } catch (GException e) { + throw new MobyException (e.getMessage(), e); + } + } + + // + protected Object sendingFilter (String input, boolean asBytes) { + if (asBytes) { + log.debug ("Data sent as a byte array"); + return input.getBytes(); + } else { + return input; + } + } + + /************************************************************************** + * Call a SOAP-based BioMoby service. In order to find what + * service to call and what are its characteristics (such as its + * endpoint) it will call method {@link #getServiceLocator} that + * should be implemented by a sub-class.

        + * + * Once it has the service locator, this class does one of the + * following, in this order:

          + * + *
        • The locator must contain at least a service name. If it + * does not, an exception is raised. + * + *
        • If the locator contains a service endpoint, a call is + * made to this endpoint, using also the service name as a + * method name. + * + *
        • If the locator has a registry endpoint, an enquiry to + * the registry is made to find an endpoint of a service + * corresponding with the given service name. Once found, the + * service is called. + * + *
        • The same as the previous one but using a default + * registry. + * + * @param xmlInput data will be sent to the called Biomoby service + * + * @return service response (still in XML) + * + * @throws MobyException (a) if service call (or a call to + * registry; for example because the registry does not know given + * service) fails, or (b) if the used {@link MobyServiceLocator} + * does not contain a service name. + * + *************************************************************************/ + public String callRemoteService (String xmlInput) + throws MobyException { + + // 1) service name is a must + MobyServiceLocator locator = getServiceLocator(); + MobyService service = locator.getService(); + if (service == null) + throw new MobyException ("MobyService locator returned an empty service object.\n" + + "I do not know what service to call..."); + String serviceName = service.getName(); + if (isEmpty (serviceName) || + MobyService.DUMMY_NAME.equals (serviceName)) + throw new MobyException ("MobyService locator returned an empty service name.\n" + + "I do not know what service to call..."); + + // 2) try service endpoint + String serviceEndpoint = service.getURL(); + if (notEmpty (serviceEndpoint)) + return callBiomobyService (locator, xmlInput); + + // 3) find service endpoint in a Biomoby registry + Central worker = new CentralImpl (locator.getRegistryEndpoint(), + locator.getRegistryNamespace()); + MobyService[] services = worker.findService (service); + if (services == null || services.length == 0) + throw new MobyException ("Service " + service.toShortString() + + " is not known in Biomoby registry: \n" + + "\t" + worker.getRegistryEndpoint() + "\n" + + "\t" + worker.getRegistryNamespace()); + // ...and call the service + serviceEndpoint = services[0].getURL(); + if (notEmpty (serviceEndpoint)) { + service.setURL (serviceEndpoint); + return callBiomobyService (locator, xmlInput); + } + + // what else can I do? + throw new MobyException ("Registry has not returned any URL for service " + + service.toShortString()); + } + + /************************************************************************** + * Fill the whole 'mobyInput' - put there any number of jobs + * (queries) as you wish (you do not need to follow the 'jobCount' + * hint suggesting how many jobs should be put there).

          + * + * Usually there is not need to overwrite this method. It serves + * as an inter-mediator between the main {@link #process} method + * and the individual request fillings (done by a sub-class in + * method {@link #fillRequest(MobyJob,MobyPackage)}).

          + * + * @return false if you wish to cancel whole request (nothing will + * be sent to a Biomoby service); otherwise return true. + * + * @param mobyInput is an empty shell that you are supposed to + * fill with the input data for a Biomoby service execution + * + * @param jobCount is only a suggestion how many requests/job + * should be created (it comes from the {@link #process} method) - + * but it does not need to be obeyed + * + *************************************************************************/ + public boolean fillRequest (MobyPackage mobyInput, int jobCount) + throws MobyException { + + if (jobCount < 0) jobCount = 0; + for (int i = 0; i < jobCount; i++) { + MobyJob request = new MobyJob ("job_" + i); + if (! fillRequest (request, mobyInput)) + break; + mobyInput.addJob (request); + } + return (mobyInput.size() > 0); + } + + /************************************************************************** + * A raw-level processing. Use it if you need access to raw XML + * coming from a service.

          + * + * @param xmlResponse is a raw XML response returned from a + * BioMoby service + * + * @return false if the response should be considered fully + * processed (in this case no other 'useResponse' will be called); + * true indicates that normal processing of the response will + * follow; by default, this class (BaseClient) returns true + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'mobyResponse' is broken + *************************************************************************/ + public boolean useResponse (String xmlResponse) + throws MobyException { + return true; + } + + /************************************************************************** + * A high-level processing. Use it if you need access to all jobs + * (queries) - that returned from a service - in the same time. + * Otherwise use the processing on the job level (method {@link + * #useResponse(MobyJob,MobyPackage)}.

          + * + * @param mobyResponse is a full response returned from a BioMoby + * service + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'mobyResponse' is broken + *************************************************************************/ + public void useResponse (MobyPackage mobyResponse) + throws MobyException { + + // iterate over all input jobs + for (int i = 0; i < mobyResponse.size(); i++) { + if (! useResponse (mobyResponse.getJob (i), + mobyResponse)) + return; + } + } + + /************************************************************************** + * Extracts errors from a raw service response. It is iseful when + * one does not want to create a whole MobyPackage from a + * response, but just find whether a response is good or bad.

          + * + * @param xmlResponse is a full response returned from a BioMoby + * service + * + * @return a slightly formatted list of exceptions (of severity + * error) extracted from the response; or null if there + * are no errors there + *************************************************************************/ + public String errorsInResponse (String xmlResponse) { + try { + StringBuffer buf = new StringBuffer(); + SAXBuilder builder = new SAXBuilder(); + Document doc = + builder.build (new StringReader (xmlResponse)); + Element root = doc.getRootElement(); + Element mobyContent = JDOMUtils.getChild (root, MobyTags.MOBYCONTENT); + Element serviceNotes = JDOMUtils.getChild (mobyContent, MobyTags.SERVICENOTES); + ServiceException[] exceptions = + ServiceException.extractExceptions (serviceNotes); + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i].getSeverity() != ServiceException.ERROR) + continue; + if (buf.length() > 0) + buf.append ("\n"); + buf.append (exceptions[i].getErrorCodeAsString()); + buf.append (": "); + buf.append (exceptions[i].getMessage()); + } + return (buf.length() == 0 ? null : new String (buf)); + + } catch (Exception e) { + return e.toString(); + } + } + + + // + // Abstract methods + // + + /************************************************************************** + * Return characteristics of a BioMoby service that will be + * called, and that reveal where to find such service.

          + * + * @see #callRemoteService + * + * @return an object defining a location of a BioMoby service + * @throws MobyException if service locator cannot be + * returned/created (e.g. because there is not enough information + * about what service to call) + *************************************************************************/ + abstract public MobyServiceLocator getServiceLocator() + throws MobyException; + + /************************************************************************** + * Crate data (fill them into 'request') for one Moby job + * (query). The request will be sent within given 'inputContext' - + * but it is not yet there (because you may wish not to put it + * there - see the return value), and it is not the task of this + * method to put it there (just fill the 'request').

          + * + * This is a method that should be implemented by a client + * developer, and it is the place where the client's business + * logic sits.

          + * + * @return true if this request should be included into the input + * data (package) that will be sent to a biomoby service; or + * return false if you do not wish to create any more requests for + * this particular package (also this 'request' will not be used) + * + * @param request is an object that you are supposed to fill with + * input data for one service invocation; it already has a name + * (so called 'query id' in the BioMoby speak) but you are free to change it + * + * @param inputContext is an envelope where all requests will be + * stored and sent to a Biomoby service; you do not need to do + * anything with it here unless you wish; note that all already + * created requests are there, but not the one you are just + * creating in this method + * + * @throws MobyException if you need so (from whatever reason in + * your business logic); if thrown then nothing will be sent to a + * Biomoby service + * + *************************************************************************/ + abstract public boolean fillRequest (MobyJob request, MobyPackage inputContext) + throws MobyException; + + /************************************************************************** + * Process a single job returned from a BioMoby service.

          + * + * This is a method that should be implemented by a client + * developer, and it is the place where the client's business + * logic using the response sits.

          + * + * @param response is an object that you are supposed to use + * + * @param responseContext is an envelope where the full response + * (all its jobs) is located; you do not need to do anything with + * it here unless you wish (e.g. it gives you knowledge about how + * many jobs are in the full response, or it gives you access to + * the so-called 'service notes') + * + * @return false if you do not wish to get any more + * responses/jobs; otherwise return true + * + * @throws MobyException if you are not satisfied with a response + * data, or from whatever reasons; it also throws this exception + * if the 'response' is broken + * + *************************************************************************/ + abstract public boolean useResponse (MobyJob response, + MobyPackage responseContext) + throws MobyException; + +} =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2006/02/19 18:42:55 1.4 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/03 15:21:13 1.5 @@ -33,6 +33,8 @@ protected String registryNamespace; protected boolean asBytes = false; protected int timeout = 0; + protected String user; + protected String password; /************************************************************************** * Default constructor. @@ -131,6 +133,44 @@ public void setAsBytes (boolean enabled) { asBytes = enabled; } - - + + /***************************************** + * Sets the user for authentication + * @param user + ***************************************/ + public void setUser(String user) { + this.user = user; + } + + /*************************************** + * Sets the password for authentication + * @param password + ***************************************/ + public void setPassword(String password) { + this.password = password; + } + + /****************************************** + * Returns the user for the authentication + * @return user + ******************************************/ + public String getUser() { + return user; + } + + /********************************************** + * Returns the password for the authentication + * @return password + **********************************************/ + public String getPassword() { + return password; + } + + /*************************************************** + * Returns true if the user AND the password is set + * @return + ***************************************************/ + public boolean hasAuthentication() { + return user != null && password != null; + } } From groscurt at dev.open-bio.org Wed Dec 3 12:09:41 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 3 Dec 2008 07:09:41 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812031209.mB3C9f1X011972@dev.open-bio.org> groscurt Wed Dec 3 07:09:40 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv11937/src/main/org/biomoby/client Modified Files: CentralImpl.java Log Message: reformatted it to the original version and removed the System.properties for the service authentication moby-live/Java/src/main/org/biomoby/client CentralImpl.java,1.58,1.59 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java,v retrieving revision 1.58 retrieving revision 1.59 diff -u -r1.58 -r1.59 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/11/26 08:53:43 1.58 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/CentralImpl.java 2008/12/03 12:09:40 1.59 @@ -69,50 +69,53 @@ import java.util.logging.*; /** - * A default implementation of the interface {@link org.biomoby.shared.Central Central} allowing access to a Moby - * registry. - *

          - * This class is supposed to be used by all other clients that wish to communicate with the Moby Registry, but do not - * want to know about all XML details that are necessary for talking with the Moby Central directly. This is an example - * of a client program: - * - *

          + * A default implementation of the
          + * interface {@link org.biomoby.shared.Central Central}
          + * allowing access to a Moby registry.
          + *

          + * This class is supposed to be used by all other clients that wish + * to communicate with the Moby Registry, but do not want to know + * about all XML details that are necessary for talking with the Moby Central + * directly. This is an example of a client program: + *

            * import org.biomoby.shared.Central;
            * import org.biomoby.shared.MobyException;
            * import org.biomoby.client.CentralImpl;
            * import java.util.Map;
            * import java.util.Iterator;
          - * 
          + *
            * public class Test {
          - * 
          - *     public static void main( String[] args ) throws MobyException {
          - * 
          - *         Central worker = new CentralImpl();
          - *         Map authorities = worker.getServiceNamesByAuthority();
          - * 
          - *         for ( Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
          - *             Map.Entry entry = ( Map.Entry ) it.next();
          - *             System.out.println( entry.getKey() );
          - *             String[] names = ( String[] ) entry.getValue();
          - *             for ( int i = 0; i < names.length; i++ )
          - *                 System.out.println( "\t" + names[ i ] );
          - *         }
          - *     }
          + *
          + *    public static void main (String[] args)
          + *       throws MobyException {
          + *
          + *       Central worker = new CentralImpl();
          + *       Map authorities = worker.getServiceNamesByAuthority();
          + *
          + *       for (Iterator it = authorities.entrySet().iterator(); it.hasNext(); ) {
          + *          Map.Entry entry = (Map.Entry)it.next();
          + *          System.out.println (entry.getKey());
          + *          String[] names = (String[])entry.getValue();
          + *          for (int i = 0; i < names.length; i++)
          + *             System.out.println ("\t" + names[i]);
          + *       }
          + *    }
            * }
          - * 
          - * + *
          + * * @author Martin Senger * @version $Id$ */ -public class CentralImpl implements Central, SimpleCache { +public class CentralImpl + implements Central, SimpleCache { private URL endpoint; private String uri; protected boolean debug = false; /** Common central used to if getDefaultCentral() is called */ - protected static Map< String, CentralImpl > defaultCentrals = new HashMap< String, CentralImpl >(); + protected static Map defaultCentrals = new HashMap(); /** Default location (endpoint) of a Moby registry. */ public static final String DEFAULT_ENDPOINT = "http://moby.ucalgary.ca/moby/MOBY-Central.pl"; @@ -121,322 +124,368 @@ public static final String DEFAULT_NAMESPACE = "http://moby.ucalgary.ca/MOBY/Central"; /** - * The META-INF resource file that will be checked to determine what default class should be instantiated in order - * to create a Central Implementation when getDefaultCentral() is called. + * The META-INF resource file that will be checked to determine what + * default class should be instantiated in order to create a Central Implementation + * when getDefaultCentral() is called. */ public static final String CENTRAL_IMPL_RESOURCE_NAME = "org.biomoby.shared.CentralDefaultImpl"; /** The class to use for getDefaultCentral if all else fails */ public static final String DEFAULT_CENTRAL_IMPL_CLASSNAME = "org.biomoby.client.CentralDigestCachedImpl"; - private static Logger logger = Logger.getLogger( "org.biomoby.client.CentralImpl" ); + private static Logger logger = Logger.getLogger("org.biomoby.client.CentralImpl"); - /** - * Thread local that gives each thread its own DocumentBuilderFactory (since it is not thread-safe). Code taken from - * Apache's JaxpUtils. - */ - public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { - protected synchronized Object initialValue() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware( true ); - return dbf; - } - }; - - /******************************************************************************************************************* - * Default constructor. It connects to a default Moby registry (as defined in {@link #DEFAULT_ENDPOINT}) using a - * default namespace (as defined int {@link #DEFAULT_NAMESPACE}). - ******************************************************************************************************************/ - public CentralImpl() throws MobyException { - this( DEFAULT_ENDPOINT, DEFAULT_NAMESPACE ); + /** + * Thread local that gives each thread its own + * DocumentBuilderFactory (since it is not thread-safe). Code taken + * from Apache's JaxpUtils. + */ + public static ThreadLocal DOCUMENT_BUILDER_FACTORIES = new ThreadLocal() { + protected synchronized Object initialValue() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware (true); + return dbf; + } + }; + + + /************************************************************************* + * Default constructor. It connects to a default Moby registry + * (as defined in {@link #DEFAULT_ENDPOINT}) using a default namespace + * (as defined int {@link #DEFAULT_NAMESPACE}). + *************************************************************************/ + public CentralImpl() + throws MobyException { + this (DEFAULT_ENDPOINT, DEFAULT_NAMESPACE); } - /******************************************************************************************************************* + /************************************************************************* * Constructor allowing to specify which Moby Registry to use. - * - * @throws MobyException - * if 'endpoint' is not a valid URL, or if no DOM parser is available - ******************************************************************************************************************/ - public CentralImpl( String endpoint ) throws MobyException { - this( endpoint, DEFAULT_NAMESPACE ); - } - - /******************************************************************************************************************* - * Constructor allowing to specify which Moby Registry and what namespace to use. If any of the parameters is null, - * its default value is used instead. - *

          - * - * @throws MobyException - * if 'endpoint' is not a valid URL, or if no DOM parser was found - ******************************************************************************************************************/ - public CentralImpl( String endpoint, String namespace ) throws MobyException { - - if ( endpoint == null || "".equals( endpoint.trim() ) ) endpoint = DEFAULT_ENDPOINT; - if ( namespace == null || "".equals( namespace.trim() ) ) namespace = DEFAULT_NAMESPACE; - - try { - this.endpoint = new URL( endpoint ); - } - catch ( MalformedURLException e ) { - throw new MobyException( "Bad URL: " + endpoint ); - } - this.uri = namespace; - - cache = new Hashtable< String, Object >(); - useCache = true; + * + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser is available + *************************************************************************/ + public CentralImpl (String endpoint) + throws MobyException { + this (endpoint, DEFAULT_NAMESPACE); + } + + /************************************************************************* + * Constructor allowing to specify which Moby Registry and what + * namespace to use. If any of the parameters is null, its default + * value is used instead. + *

          + * @throws MobyException if 'endpoint' is not a valid URL, or if no + * DOM parser was found + *************************************************************************/ + public CentralImpl (String endpoint, String namespace) + throws MobyException { + + if (endpoint == null || "".equals (endpoint.trim())) + endpoint = DEFAULT_ENDPOINT; + if (namespace == null || "".equals (namespace.trim())) + namespace = DEFAULT_NAMESPACE; + + try { + this.endpoint = new URL (endpoint); + } catch (MalformedURLException e) { + throw new MobyException ("Bad URL: " + endpoint); + } + this.uri = namespace; + + cache = new Hashtable(); + useCache = true; + } + + /************************************************************************* + * Loads a DOM Document from an InputStream. Uses thread-safe + * mechanism. + *************************************************************************/ + public static Document loadDocument (InputStream input) + throws MobyException { + try { + DocumentBuilderFactory dbf + = (DocumentBuilderFactory)DOCUMENT_BUILDER_FACTORIES.get(); + DocumentBuilder db = dbf.newDocumentBuilder(); + return (db.parse (input)); + } catch (Exception e) { + throw new MobyException ("Problem with reading XML input: " + e.toString(), e); } - - /******************************************************************************************************************* - * Loads a DOM Document from an InputStream. Uses thread-safe mechanism. - ******************************************************************************************************************/ - public static Document loadDocument( InputStream input ) throws MobyException { - try { - DocumentBuilderFactory dbf = ( DocumentBuilderFactory ) DOCUMENT_BUILDER_FACTORIES.get(); - DocumentBuilder db = dbf.newDocumentBuilder(); - return ( db.parse( input ) ); - } - catch ( Exception e ) { - throw new MobyException( "Problem with reading XML input: " + e.toString(), e ); - } } - /******************************************************************************************************************* + /************************************************************************* * Call 'method' with 'parameters' and return its result. - ******************************************************************************************************************/ - protected Object doCall( String method, Object[] parameters ) throws MobyException { - - Call call = null; - try { - Service service = new Service(); - call = ( Call ) service.createCall(); - call.setTargetEndpointAddress( endpoint ); - call.setTimeout( new Integer( 0 ) ); - - String user = System.getProperty( "user" ); - String password = System.getProperty( "password" ); - - if ( user != null && password != null ) { - call.setProperty( Call.USERNAME_PROPERTY, user ); - call.setProperty( Call.PASSWORD_PROPERTY, password ); - } - - call.setSOAPActionURI( uri + "#" + method ); - - if ( debug ) { - System.err.println( "METHOD CALL: " + method ); - System.err.println( "------------" ); - if ( parameters.length > 0 ) System.err.println( parameters[ 0 ] + "\n" ); - System.err.println( "------------\n" ); - - Object result = call.invoke( uri, method, parameters ); - - System.err.println( "METHOD RETURN:" ); - System.err.println( "------------" ); - if ( result != null ) System.err.println( result + "\n" ); - System.err.println( "------------\n" ); - - return resultToString( result ); - - } - else { - return resultToString( call.invoke( uri, method, parameters ) ); - } - - } - catch ( AxisFault e ) { - throw new MobyException( formatFault( e, endpoint.toString(), ( call == null ? null : call - .getOperationName() ) ), e ); - // (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); - - } - catch ( Exception e ) { - throw new MobyException( e.toString(), e ); - // e.printStackTrace(); - } - } - - /******************************************************************************************************************* - * Parse the given XML sniplet to find tag 'success'. If it has value '1' look further for tag 'id' and return it - * back (or return an empty string if ID is not there). Otherwise raise an exception with the 'culprit' and with the - * message from the tag 'message'. - *

          - * - * The return value is a two-element long array. The first element is the ID (given by BioMobe registry), and the - * second element is RDF corresponding with the registered object (BioMoby returns this only for service instances, - * so for other objects this will be null). - *

          - * - * This is how the XML is supposed to look: - * - * Success takes the value "1" to indicate success, "0" to indicate failure, and "-1" to indicate "Pending - * Curation". - ******************************************************************************************************************/ - protected String[] checkRegistration( String xml, Object culprit ) throws MobyException, NoSuccessException, - PendingCurationException { - - String id = "", success = "0", message = "", rdf = ""; - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( xml.getBytes() ) ); - Element root = document.getDocumentElement(); - - NodeList children = root.getChildNodes(); - for ( int i = 0; i < children.getLength(); i++ ) { - if ( children.item( i ).getNodeType() != Node.ELEMENT_NODE ) continue; - Element elem = ( Element ) children.item( i ); - if ( elem.getNodeName().equals( "id" ) ) { - if ( elem.getFirstChild() != null ) id = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "success" ) ) { - if ( elem.getFirstChild() != null ) success = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "message" ) ) { - if ( elem.getFirstChild() != null ) message = elem.getFirstChild().getNodeValue(); - } - else if ( elem.getNodeName().equals( "RDF" ) ) { - if ( elem.getFirstChild() != null ) rdf = elem.getFirstChild().getNodeValue(); - } - } - - if ( success.equals( "0" ) ) - throw new NoSuccessException( message, culprit ); - else if ( success.equals( "-1" ) ) throw new PendingCurationException(); - return new String[] { id, rdf }; - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing input data types and their usage in the given - * service. Only data considered primary are included. Note that the main job of converting to XML is done by - * instances of MobyPrimaryData. - * - * The returned XML looks like this: - ******************************************************************************************************************/ - protected String buildPrimaryInputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryInputs = service.getPrimaryInputs(); - buf.append( "\n" ); - for ( int i = 0; i < primaryInputs.length; i++ ) - buf.append( primaryInputs[ i ].toXML() ); - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing input data types and their usage in the given - * service. Only data considered secondary are included. Note that the main job of converting to XML is done by - * instances of MobySecondaryData. - * - * The returned XML looks like this: - * - ******************************************************************************************************************/ - protected String buildSecondaryInputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] secInputs = service.getSecondaryInputs(); - buf.append( "\n" ); - for ( int i = 0; i < secInputs.length; i++ ) { - buf.append( secInputs[ i ].toXML() ); - } - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML created from the definitions representing output data types and their usage in the given - * service. Only data considered primary are included. Note that the main job of converting to XML is done by - * instances of MobyPrimaryData. - * - * The returned XML looks like this: - * - * - ******************************************************************************************************************/ - protected String buildOutputTag( MobyService service ) { - StringBuffer buf = new StringBuffer(); - MobyData[] primaryOutputs = service.getPrimaryOutputs(); - buf.append( "\n" ); - for ( int i = 0; i < primaryOutputs.length; i++ ) - buf.append( primaryOutputs[ i ].toXML() ); - buf.append( "\n" ); - return new String( buf ); - } - - /******************************************************************************************************************* - * Return a piece of XML represented a query object (an object used to find a service). - * + *************************************************************************/ + protected Object doCall (String method, Object[] parameters) + throws MobyException { + + Call call = null; + try { + Service service = new Service(); + call = (Call) service.createCall(); + call.setTargetEndpointAddress (endpoint); + call.setTimeout (new Integer (0)); + + call.setSOAPActionURI (uri + "#" + method); + + if (debug) { + System.err.println ("METHOD CALL: " + method); + System.err.println ("------------"); + if (parameters.length > 0) + System.err.println (parameters[0] + "\n"); + System.err.println ("------------\n"); + + Object result = call.invoke (uri, method, parameters); + + System.err.println ("METHOD RETURN:"); + System.err.println ("------------"); + if (result != null) + System.err.println (result + "\n"); + System.err.println ("------------\n"); + + return resultToString (result); + + } else { + return resultToString (call.invoke (uri, method, parameters)); + } + + } catch (AxisFault e) { + throw new MobyException + (formatFault (e, + endpoint.toString(), + (call == null ? null : call.getOperationName())), + e); +// (endpoint.toString()+(call == null ? "" : call.getOperationName()), e); + + } catch (Exception e) { + throw new MobyException (e.toString(), e); +// e.printStackTrace(); + } + } + + + /************************************************************************** + * Parse the given XML sniplet to find tag 'success'. If it has value '1' + * look further for tag 'id' and return it back (or return an empty string + * if ID is not there). Otherwise raise an exception with the 'culprit' + * and with the message from the tag 'message'.

          + * + * The return value is a two-element long array. The first element + * is the ID (given by BioMobe registry), and the second element + * is RDF corresponding with the registered object (BioMoby + * returns this only for service instances, so for other objects + * this will be null).

          + * + * This is how the XML is supposed to look: + * + * + * + * + * + * + * + * Success takes the value "1" to indicate success, "0" to + * indicate failure, and "-1" to indicate "Pending Curation". + *************************************************************************/ + protected String[] checkRegistration (String xml, Object culprit) + throws MobyException, NoSuccessException, PendingCurationException { + + String id = "", success = "0", message = "", rdf = ""; + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + Element root = document.getDocumentElement(); + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + if (children.item (i).getNodeType() != Node.ELEMENT_NODE) + continue; + Element elem = (Element)children.item (i); + if (elem.getNodeName().equals ("id")) { + if (elem.getFirstChild() != null) + id = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals("success")) { + if (elem.getFirstChild() != null) + success = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("message")) { + if (elem.getFirstChild() != null) + message = elem.getFirstChild().getNodeValue(); + } else if (elem.getNodeName().equals ("RDF")) { + if (elem.getFirstChild() != null) + rdf = elem.getFirstChild().getNodeValue(); + } + } + + if (success.equals ("0")) + throw new NoSuccessException (message, culprit); + else if (success.equals ("-1")) + throw new PendingCurationException(); + return new String[] { id, rdf }; + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * * The returned XML looks like this: - * - * - * - * ServiceTypeTerm ServiceName moby - * http://desired.service.provider; 1|0 1|0 - * 1|0 something .... .... - ******************************************************************************************************************/ - protected String buildQueryObject( MobyService service, String[] keywords, boolean expandObjects, - boolean expandServices, boolean authoritative ) { - if ( service == null ) { - service = new MobyService( "dummy" ); - service.setCategory( "" ); - } - StringBuffer buf = new StringBuffer(); - - buf.append( "\n\n" ); - MobyData[] pi = service.getPrimaryInputs(); - if ( pi.length > 0 ) { - for ( int i = 0; i < pi.length; i++ ) - buf.append( pi[ i ].toXML() ); - } - buf.append( "\n\n" ); - - buf.append( "\n\n" ); - MobyData[] po = service.getPrimaryOutputs(); - if ( po.length > 0 ) { - for ( int i = 0; i < po.length; i++ ) - buf.append( po[ i ].toXML() ); - } - buf.append( "\n\n" ); - - buf.append( "" + service.getType() + "\n" ); - - String name = service.getName(); - if ( !name.equals( "" ) && !name.equals( "dummy" ) && !name.equals( MobyService.DUMMY_NAME ) ) - buf.append( "" + service.getName() + "\n" ); - - String sigURL = service.getSignatureURL(); - if ( !sigURL.equals( "" ) ) buf.append( "" + sigURL + "\n" ); - - buf.append( "" + service.getCategory() + "\n" ); - buf.append( "" + service.getAuthority() + "\n" ); - - buf.append( "" ); - buf.append( expandObjects ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "" ); - buf.append( expandServices ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "" ); - buf.append( authoritative ? "1" : "0" ); - buf.append( "\n" ); - - buf.append( "\n" ); - if ( keywords != null && keywords.length > 0 ) { - for ( int i = 0; i < keywords.length; i++ ) { - buf.append( "" ); - buf.append( keywords[ i ] ); - buf.append( "\n" ); - } - } - buf.append( "\n" ); - - return new String( buf ); - } - - /******************************************************************************************************************* - * Extract one or more MobyService objects from the given XML piece. The XML should look like this: - * + * + * + * + *************************************************************************/ + protected String buildPrimaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryInputs = service.getPrimaryInputs(); + buf.append ("\n"); + for (int i = 0; i < primaryInputs.length; i++) + buf.append (primaryInputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing input + * data types and their usage in the given service. Only data considered + * secondary are included. Note that the main job of converting to XML is + * done by instances of MobySecondaryData. + * + * The returned XML looks like this: + * + * + * + *************************************************************************/ + protected String buildSecondaryInputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] secInputs = service.getSecondaryInputs(); + buf.append ("\n"); + for (int i = 0; i < secInputs.length; i++) { + buf.append (secInputs[i].toXML()); + } + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML created from the definitions representing output + * data types and their usage in the given service. Only data considered + * primary are included. Note that the main job of converting to XML is + * done by instances of MobyPrimaryData. + * + * The returned XML looks like this: + * + * + * + * + *************************************************************************/ + protected String buildOutputTag (MobyService service) { + StringBuffer buf = new StringBuffer(); + MobyData[] primaryOutputs = service.getPrimaryOutputs(); + buf.append ("\n"); + for (int i = 0; i < primaryOutputs.length; i++) + buf.append (primaryOutputs[i].toXML()); + buf.append ("\n"); + return new String (buf); + } + + /************************************************************************** + * Return a piece of XML represented a query object (an object used + * to find a service). + * + * The returned XML looks like this: + * + * + * + * + * + * + * + * + * + * + * + * ServiceTypeTerm + * ServiceName + * moby + * http://desired.service.provider; + * 1|0 + * 1|0 + * 1|0 + * + * something + * .... + * .... + * + *************************************************************************/ + protected String buildQueryObject (MobyService service, + String[] keywords, + boolean expandObjects, + boolean expandServices, + boolean authoritative) { + if (service == null) { + service = new MobyService ("dummy"); + service.setCategory (""); + } + StringBuffer buf = new StringBuffer(); + + buf.append ("\n\n"); + MobyData[] pi = service.getPrimaryInputs(); + if (pi.length > 0) { + for (int i = 0; i < pi.length; i++) + buf.append (pi[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("\n\n"); + MobyData[] po = service.getPrimaryOutputs(); + if (po.length > 0) { + for (int i = 0; i < po.length; i++) + buf.append (po[i].toXML()); + } + buf.append ("\n\n"); + + buf.append ("" + service.getType() + "\n"); + + String name = service.getName(); + if (!name.equals ("") && !name.equals ("dummy") && !name.equals (MobyService.DUMMY_NAME)) + buf.append ("" + service.getName() + "\n"); + + String sigURL = service.getSignatureURL(); + if (!sigURL.equals ("")) + buf.append ("" + sigURL + "\n"); + + buf.append ("" + service.getCategory() + "\n"); + buf.append ("" + service.getAuthority() + "\n"); + + buf.append (""); + buf.append (expandObjects ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (expandServices ? "1" : "0"); + buf.append ("\n"); + + buf.append (""); + buf.append (authoritative ? "1" : "0"); + buf.append ("\n"); + + buf.append ("\n"); + if (keywords != null && keywords.length > 0) { + for (int i = 0; i < keywords.length; i++) { + buf.append (""); + buf.append (keywords[i]); + buf.append ("\n"); + } + } + buf.append ("\n"); + + return new String (buf); + } + + /************************************************************************** + * Extract one or more MobyService objects from the given XML piece. + * The XML should look like this: *

                *  <Services>
          -     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
          +     *    <Service authURI="authority.URI.here" lsid="..." serviceName="MyService">
                *      <serviceType>Service_Ontology_Term</serviceType>
                *      <Category>moby</Category> <!-- or 'cgi' or 'soap' -->
                *      <contactEmail>your at email.addy.here</contactEmail>
          @@ -459,359 +508,359 @@
                *    ...
                *  </Services>
                * 
          - * - * @throws MobyException - * if the XML document is invalid - ******************************************************************************************************************/ - public MobyService[] extractServices( String xml ) throws MobyException { - - Document document = loadDocument( new ByteArrayInputStream( xml.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Service" ); - MobyService[] results = new MobyService[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyService service = new MobyService( elem.getAttribute( "serviceName" ) ); - service.setAuthority( elem.getAttribute( "authURI" ) ); - service.setLSID( elem.getAttribute( "lsid" ) ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "Description" ) ) { - service.setDescription( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "Category" ) ) { - service.setCategory( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "URL" ) ) { - service.setURL( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "signatureURL" ) ) { - service.setSignatureURL( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "contactEmail" ) ) { - service.setEmailContact( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "serviceType" ) ) { - service.setType( getFirstValue( children.item( j ) ) ); - MobyServiceType mst = new MobyServiceType( service.getType() ); - NamedNodeMap map = ( children.item( j ).getAttributes() ); - if ( map != null ) { - Node node = map.getNamedItemNS( children.item( j ).getNamespaceURI(), "lsid" ); - if ( node != null ) mst.setLSID( node.getNodeValue() ); - } - service.setServiceType( mst ); - } - else if ( nodeName.equals( "authoritative" ) ) { - String authoritative = getFirstValue( children.item( j ) ); - service.setAuthoritative( authoritative.equals( "1" ) ? true : false ); - } - else if ( nodeName.equals( "Input" ) ) { - // - // - // - // ... - // - // - // ...... - // ...... - // - // - NodeList inputs = children.item( j ).getChildNodes(); - for ( int k = 0; k < inputs.getLength(); k++ ) { - if ( inputs.item( k ).getNodeName().equals( "Simple" ) ) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple( ( Element ) inputs.item( k ) ); - service.addInput( data ); - } - else if ( inputs.item( k ).getNodeName().equals( "Collection" ) ) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet( ( Element ) inputs.item( k ) ); - service.addInput( data ); - } - } - } - else if ( nodeName.equals( "Output" ) ) { - // - // - // - NodeList inputs = children.item( j ).getChildNodes(); - for ( int k = 0; k < inputs.getLength(); k++ ) { - if ( inputs.item( k ).getNodeName().equals( "Simple" ) ) { - MobyPrimaryDataSimple data = new MobyPrimaryDataSimple( ( Element ) inputs.item( k ) ); - service.addOutput( data ); - } - else if ( inputs.item( k ).getNodeName().equals( "Collection" ) ) { - MobyPrimaryDataSet data = new MobyPrimaryDataSet( ( Element ) inputs.item( k ) ); - service.addOutput( data ); - } - } - - } - else if ( nodeName.equals( "secondaryArticles" ) ) { - // - // ... - // - NodeList parameters = children.item( j ).getChildNodes(); - for ( int k = 0; k < parameters.getLength(); k++ ) { - if ( parameters.item( k ).getNodeName().equals( "Parameter" ) ) { - MobySecondaryData data = new MobySecondaryData( ( Element ) parameters.item( k ) ); - service.addInput( data ); - } - } - } + * @throws MobyException if the XML document is invalid + *************************************************************************/ + public MobyService[] extractServices (String xml) + throws MobyException { + + Document document = loadDocument (new ByteArrayInputStream (xml.getBytes())); + NodeList list = document.getElementsByTagName ("Service"); + MobyService[] results = new MobyService [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyService service = new MobyService (elem.getAttribute ("serviceName")); + service.setAuthority (elem.getAttribute ("authURI")); + service.setLSID (elem.getAttribute ("lsid")); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + service.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Category")) { + service.setCategory (getFirstValue (children.item (j))); + } else if (nodeName.equals ("URL")) { + service.setURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("signatureURL")) { + service.setSignatureURL (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + service.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("serviceType")) { + service.setType (getFirstValue (children.item (j))); + MobyServiceType mst = new MobyServiceType(service.getType()); + NamedNodeMap map = (children.item (j).getAttributes()); + if (map != null) { + Node node = map.getNamedItemNS(children.item(j).getNamespaceURI(),"lsid"); + if (node != null) + mst.setLSID(node.getNodeValue()); + } + service.setServiceType(mst); + } else if (nodeName.equals ("authoritative")) { + String authoritative = getFirstValue (children.item (j)); + service.setAuthoritative (authoritative.equals ("1") ? true : false); + } else if (nodeName.equals ("Input")) { + // + // + // + // ... + // + // + // ...... + // ...... + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addInput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addInput (data); + } + } + } else if (nodeName.equals ("Output")) { + // + // + // + NodeList inputs = children.item (j).getChildNodes(); + for (int k = 0; k < inputs.getLength(); k++) { + if (inputs.item (k).getNodeName().equals ("Simple")) { + MobyPrimaryDataSimple data = new MobyPrimaryDataSimple ((Element)inputs.item (k)); + service.addOutput (data); + } else if (inputs.item (k).getNodeName().equals ("Collection")) { + MobyPrimaryDataSet data = new MobyPrimaryDataSet ((Element)inputs.item (k)); + service.addOutput (data); + } + } + + } else if (nodeName.equals ("secondaryArticles")) { + // + // ... + // + NodeList parameters = children.item (j).getChildNodes(); + for (int k = 0; k < parameters.getLength(); k++) { + if (parameters.item (k).getNodeName().equals ("Parameter")) { + MobySecondaryData data = new MobySecondaryData ((Element)parameters.item (k)); + service.addInput (data); + } } - results[ i ] = service; } - return results; + } + results [i] = service; + } + return results; } // protect against null values - protected String getFirstValue( Node child ) { - Node node = child.getFirstChild(); - if ( node == null ) return ""; - String value = node.getNodeValue(); - if ( value == null ) return ""; - return value; + protected String getFirstValue (Node child) { + Node node = child.getFirstChild(); + if (node == null) return ""; + String value = node.getNodeValue(); + if (value == null) return ""; + return value; + } + + protected String getFirstValue (NodeList children) { + if (children.item(0) != null && children.item(0).hasChildNodes()) { + children.item(0).normalize(); + return getFirstValue (children.item(0)); } - - protected String getFirstValue( NodeList children ) { - if ( children.item( 0 ) != null && children.item( 0 ).hasChildNodes() ) { - children.item( 0 ).normalize(); - return getFirstValue( children.item( 0 ) ); - } - return ""; + return ""; } - /******************************************************************************************************************* + /************************************************************************** * * Implementing SimpleCache interface. - * - * Why to have an interface for such trivial thing? Well, because I needed to overwrite the caching mechanism in the - * subclasses so I needed to have all caching functions as separate methods - that's why I have collect them in an - * interface. - * - ******************************************************************************************************************/ - private Hashtable< String, Object > cache; // this is the cache itself - private boolean useCache; // this signal that we are actually caching things + * + * Why to have an interface for such trivial thing? Well, because + * I needed to overwrite the caching mechanism in the subclasses + * so I needed to have all caching functions as separate methods - + * that's why I have collect them in an interface. + * + *************************************************************************/ + private Hashtable cache; // this is the cache itself + private boolean useCache; // this signal that we are actually caching things // not used here - public String createId( String rootName, String semanticType, String syntaxType, long lastModified, Properties props ) { - return ""; // not used here + public String createId (String rootName, + String semanticType, String syntaxType, + long lastModified, + Properties props) { + return ""; // not used here } // check existence of a cached object - public boolean existsInCache( String id ) { - synchronized ( cache ) { - if ( useCache ) - return cache.containsKey( id ); - else - return false; - } + public boolean existsInCache (String id) { + synchronized (cache) { + if (useCache) return cache.containsKey (id); + else return false; + } } // retrieve from cache - public Object getContents( String id ) { - synchronized ( cache ) { - if ( useCache ) - return cache.get( id ); - else - return null; - } + public Object getContents (String id) { + synchronized (cache) { + if (useCache) return cache.get (id); + else return null; + } } // cache an object - public void setContents( String id, java.lang.Object data ) { - synchronized ( cache ) { - if ( useCache ) cache.put( id, data ); - } + public void setContents (String id, java.lang.Object data) { + synchronized (cache) { + if (useCache) cache.put (id, data); + } } // in this implementation, it clears the whole cache, regardless // what 'id' is passed - public void removeFromCache( String id ) { - cache.clear(); + public void removeFromCache (String id) { + cache.clear(); } - /******************************************************************************************************************* - * - * And the other methods related to caching (but not part of the SimpleCache interface). - * - ******************************************************************************************************************/ - - /******************************************************************************************************************* - * By default, caching is enabled to reduce network traffic. Setting this to false will clear the cache, and not - * cache any further calls unless it is set to true again. - *

          - * - * @param shouldCache - * whether retrieveXXX call results should be cached in case they are called again (i.e. don't request - * MobyCentral every time) - ******************************************************************************************************************/ - public void setCacheMode( boolean shouldCache ) { - useCache = shouldCache; - if ( !useCache ) removeFromCache( null ); + /************************************************************************** + * + * And the other methods related to caching (but not part of the + * SimpleCache interface). + * + **************************************************************************/ + + /************************************************************************** + * By default, caching is enabled to reduce network traffic. + * Setting this to false will clear the cache, and not cache any + * further calls unless it is set to true again.

          + * + * @param shouldCache whether retrieveXXX call results should be + * cached in case they are called again (i.e. don't request + * MobyCentral every time) + **************************************************************************/ + public void setCacheMode (boolean shouldCache) { + useCache = shouldCache; + if (! useCache) + removeFromCache (null); } - /******************************************************************************************************************* + /************************************************************************** * Find if caching is currently enabled. - * + * * @return true if caching is enabled - ******************************************************************************************************************/ - public boolean getCacheMode() { - return useCache; + **************************************************************************/ + public boolean getCacheMode(){ + return useCache; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

                * <serviceNames>
          -     *   <serviceName name="serviceName" authURI='authority.info.here'/>
          +     *   <serviceName name="serviceName" authURI='authority.info.here'/>
                *   ...
                *   ...
                * </serviceNames>
                * 
          - * - * @deprecated Replaced by {@link #getServiceNamesByAuthority}. The reason is that this method returns a random - * result if there are more services with the same name but belonging to different authorities. - *

          - * - ******************************************************************************************************************/ - public Map< String, String > getServiceNames() throws MobyException { - - String result = ( String ) doCall( "retrieveServiceNames", new Object[] {} ); - // parse returned XML - Map< String, String > results = new TreeMap< String, String >( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceName" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - results.put( elem.getAttribute( "name" ), elem.getAttribute( "authURI" ) ); - } + * + * @deprecated Replaced by {@link + * #getServiceNamesByAuthority}. The reason is that this method + * returns a random result if there are more services with the + * same name but belonging to different authorities.

          + * + *************************************************************************/ + public Map getServiceNames() + throws MobyException { + + String result = (String)doCall ("retrieveServiceNames", + new Object[] {}); + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + results.put (elem.getAttribute ("name"), + elem.getAttribute ("authURI")); + } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

                * <serviceNames>
          -     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
          +     *   <serviceName name="serviceName" lsid="..." authURI='authority.info.here'/>
                *   ...
                *   ...
                * </serviceNames>
                * 
          - * - * @return a Map which has authorities as keys, and String arrays with service names as a values. - ******************************************************************************************************************/ - public Map getServiceNamesByAuthority() throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML( result, true ); - } - - /******************************************************************************************************************* - * Similar to {@link #getServiceNamesByAuthority} but the resulting Map contains slightly more. - *

          - * - * @return a Map which has authorities as keys, and arrays of MobyServices as a values. Each MobyService is filled - * with its name, authority and LSID. - ******************************************************************************************************************/ - public Map getServicesByAuthority() throws MobyException { - String result = getServiceNamesByAuthorityAsXML(); - return createServicesByAuthorityFromXML( result, false ); + * + * @return a Map which has authorities as keys, and String arrays + * with service names as a values. + *************************************************************************/ + public Map getServiceNamesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, true); + } + + /************************************************************************** + * Similar to {@link #getServiceNamesByAuthority} but the + * resulting Map contains slightly more.

          + * + * @return a Map which has authorities as keys, and arrays of + * MobyServices as a values. Each MobyService is filled with its + * name, authority and LSID. + *************************************************************************/ + public Map getServicesByAuthority() + throws MobyException { + String result = getServiceNamesByAuthorityAsXML(); + return createServicesByAuthorityFromXML (result, false); } // - protected String getServiceNamesByAuthorityAsXML() throws MobyException { - return ( String ) doCall( "retrieveServiceNames", new Object[] {} ); + protected String getServiceNamesByAuthorityAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceNames", + new Object[] {}); } // if onlyNames == true - // Map: authority name -> String[] - // (filled with service namea) + // Map: authority name -> String[] + // (filled with service namea) // else - // Map: authority name -> MobyService[] - // (filled with service name, authority and lsid) - protected Map createServicesByAuthorityFromXML( String result, boolean onlyNames ) throws MobyException { - - // parse returned XML - Map results = new TreeMap( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceName" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String name = elem.getAttribute( "name" ); - String auth = elem.getAttribute( "authURI" ); - Vector< Object > v = ( results.containsKey( auth ) ? ( Vector ) results.get( auth ) - : new Vector< Object >() ); - if ( onlyNames ) { - v.addElement( name ); - } - else { - MobyService ms = new MobyService( name ); - ms.setAuthority( auth ); - ms.setLSID( elem.getAttribute( "lsid" ) ); - v.addElement( ms ); - } - results.put( auth, v ); - } - - // change values of type Vector to MobyService[] or String[] - for ( Iterator it = results.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = ( Map.Entry ) it.next(); - Vector v = ( Vector ) entry.getValue(); - if ( onlyNames ) { - String[] sNames = new String[ v.size() ]; - v.copyInto( sNames ); - entry.setValue( sNames ); - } - else { - MobyService[] mss = new MobyService[ v.size() ]; - v.copyInto( mss ); - entry.setValue( mss ); - } + // Map: authority name -> MobyService[] + // (filled with service name, authority and lsid) + protected Map createServicesByAuthorityFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceName"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + String auth = elem.getAttribute ("authURI"); + Vector v = + (results.containsKey (auth) ? (Vector)results.get (auth) : new Vector()); + if (onlyNames) { + v.addElement (name); + } else { + MobyService ms = new MobyService (name); + ms.setAuthority (auth); + ms.setLSID (elem.getAttribute ("lsid")); + v.addElement (ms); + } + results.put (auth, v); + } + + // change values of type Vector to MobyService[] or String[] + for (Iterator it = results.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + Vector v = (Vector)entry.getValue(); + if (onlyNames) { + String[] sNames = new String [v.size()]; + v.copyInto (sNames); + entry.setValue (sNames); + } else { + MobyService[] mss = new MobyService [v.size()]; + v.copyInto (mss); + entry.setValue (mss); } + } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
                *  <serviceProviders>
          -     *     <serviceProvider name="authority.URI.here"/>
          +     *     <serviceProvider name="authority.URI.here"/>
                *          ...
                *          ...
                *  </serviceProviders>
                * 
          - ******************************************************************************************************************/ - public String[] getProviders() throws MobyException { + *************************************************************************/ + public String[] getProviders() + throws MobyException { - String cacheId = "retrieveServiceProviders"; - String[] cachedResults = ( String[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; + String cacheId = "retrieveServiceProviders"; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; - String result = ( String ) doCall( "retrieveServiceProviders", new Object[] {} ); + String result = (String)doCall ("retrieveServiceProviders", + new Object[] {}); - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceProvider" ); - String[] results = new String[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) - results[ i ] = ( ( Element ) list.item( i ) ).getAttribute( "name" ); + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceProvider"); + String[] results = new String [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) + results[i] = ((Element)list.item (i)).getAttribute ("name"); - // Add this data to the cache in case we get called again - setContents( cacheId, results ); + // Add this data to the cache in case we get called again + setContents (cacheId, results); - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
                *  <serviceTypes>
          -     *     <serviceType name="serviceName" lsid="...">
          +     *     <serviceType name="serviceName" lsid="...">
                *            <Description><![CDATA[free text description here]]></Description>
                *            <contactEmail>...</contactEmail>
                *            <authURI>...</authURI>
          @@ -820,52 +869,57 @@
                *          ...
                *  </serviceTypes>
                * 
          - ******************************************************************************************************************/ - public Map getServiceTypes() throws MobyException { - String result = getServiceTypesAsXML(); - Map results = new TreeMap( getStringComparator() ); - MobyServiceType[] types = createServiceTypesFromXML( result ); - for ( int i = 0; i < types.length; i++ ) { - results.put( types[ i ].getName(), types[ i ].getDescription() ); - } - return results; + *************************************************************************/ + public Map getServiceTypes() + throws MobyException { + String result = getServiceTypesAsXML(); + Map results = new TreeMap (getStringComparator()); + MobyServiceType[] types = createServiceTypesFromXML (result); + for (int i = 0; i < types.length; i++) { + results.put (types[i].getName(), + types[i].getDescription()); + } + return results; } // - protected String getServiceTypesAsXML() throws MobyException { - return ( String ) doCall( "retrieveServiceTypes", new Object[] {} ); + protected String getServiceTypesAsXML() + throws MobyException { + return (String)doCall ("retrieveServiceTypes", + new Object[] {}); } // but be aware that the created MobyServiceTypes are not complete // - they do not have the relationship information; that's why // this method is not public; the full service types are available // from CentralDigest implementations - protected MobyServiceType[] createServiceTypesFromXML( String result ) throws MobyException { + protected MobyServiceType[] createServiceTypesFromXML (String result) + throws MobyException { - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "serviceType" ); - if ( list == null || list.getLength() == 0 ) return new MobyServiceType[] {}; - MobyServiceType[] results = new MobyServiceType[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyServiceType st = new MobyServiceType( elem.getAttribute( "name" ) ); - st.setLSID( elem.getAttribute( "lsid" ) ); - st.setDescription( getFirstValue( elem.getElementsByTagName( "Description" ) ) ); - st.setEmailContact( getFirstValue( elem.getElementsByTagName( "contactEmail" ) ) ); - st.setAuthority( getFirstValue( elem.getElementsByTagName( "authURI" ) ) ); - results[ i ] = st; - } - java.util.Arrays.sort( results ); - return results; + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("serviceType"); + if (list == null || list.getLength() == 0) + return new MobyServiceType[] {}; + MobyServiceType[] results = new MobyServiceType [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyServiceType st = new MobyServiceType (elem.getAttribute ("name")); + st.setLSID (elem.getAttribute ("lsid")); + st.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + st.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + st.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = st; + } + java.util.Arrays.sort (results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
                *  <Namespaces>
          -     *     <Namespace name="namespace" lsid="...">
          +     *     <Namespace name="namespace" lsid="...">
                *            <Description><![CDATA[free text description here]]></Description>
                *            <contactEmail>...</contactEmail>
                *            <authURI>...</authURI>
          @@ -874,122 +928,133 @@
                *          ...
                *  </Namespaces>
                * 
          - ******************************************************************************************************************/ - public MobyNamespace[] getFullNamespaces() throws MobyException { + *************************************************************************/ + public MobyNamespace[] getFullNamespaces() + throws MobyException { - String result = getNamespacesAsXML(); - return createNamespacesFromXML( result ); + String result = getNamespacesAsXML(); + return createNamespacesFromXML (result); } // - protected String getNamespacesAsXML() throws MobyException { - return ( String ) doCall( "retrieveNamespaces", new Object[] {} ); + protected String getNamespacesAsXML() + throws MobyException { + return (String)doCall ("retrieveNamespaces", + new Object[] {}); } // - protected MobyNamespace[] createNamespacesFromXML( String result ) throws MobyException { - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getDocumentElement().getElementsByTagName( "Namespace" ); - if ( list == null || list.getLength() == 0 ) { - return new MobyNamespace[] {}; - } - MobyNamespace[] results = new MobyNamespace[ list.getLength() ]; - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - MobyNamespace nm = new MobyNamespace( elem.getAttribute( "name" ) ); - nm.setLSID( elem.getAttribute( "lsid" ) ); - nm.setDescription( getFirstValue( elem.getElementsByTagName( "Description" ) ) ); - nm.setEmailContact( getFirstValue( elem.getElementsByTagName( "contactEmail" ) ) ); - nm.setAuthority( getFirstValue( elem.getElementsByTagName( "authURI" ) ) ); - results[ i ] = nm; - } + protected MobyNamespace[] createNamespacesFromXML (String result) + throws MobyException { - java.util.Arrays.sort( results ); - return results; + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getDocumentElement().getElementsByTagName ("Namespace"); + if (list == null || list.getLength() == 0) { + return new MobyNamespace[] {}; + } + MobyNamespace[] results = new MobyNamespace [list.getLength()]; + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + MobyNamespace nm = new MobyNamespace (elem.getAttribute ("name")); + nm.setLSID (elem.getAttribute ("lsid")); + nm.setDescription (getFirstValue (elem.getElementsByTagName ("Description"))); + nm.setEmailContact (getFirstValue (elem.getElementsByTagName ("contactEmail"))); + nm.setAuthority (getFirstValue (elem.getElementsByTagName ("authURI"))); + results[i] = nm; + } + + java.util.Arrays.sort (results); + return results; + } + + /************************************************************************** + * + * @deprecated Replaced by {@link #getFullNamespaces} that gives + * more information for the same price.

          + *************************************************************************/ + public Map getNamespaces() + throws MobyException { + + Map results = new TreeMap (getStringComparator()); + MobyNamespace[] namespaces = getFullNamespaces(); + for (int i = 0; i < namespaces.length; i++) { + results.put (namespaces[i].getName(), + namespaces[i].getDescription()); } - - /******************************************************************************************************************* - * - * @deprecated Replaced by {@link #getFullNamespaces} that gives more information for the same price. - *

          - ******************************************************************************************************************/ - public Map getNamespaces() throws MobyException { - - Map results = new TreeMap( getStringComparator() ); - MobyNamespace[] namespaces = getFullNamespaces(); - for ( int i = 0; i < namespaces.length; i++ ) { - results.put( namespaces[ i ].getName(), namespaces[ i ].getDescription() ); - } - return results; + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *

                *  <objectNames>
          -     *     <Object name="objectName" lsid="...">
          +     *     <Object name="objectName" lsid="...">
                *            <Description><![CDATA[free text description here]]></Description>
                *     </Object>
                *          ...
                *          ...
                *  </objectNames>
                * 
          - ******************************************************************************************************************/ - public Map getDataTypeNames() throws MobyException { - String result = getDataTypeNamesAsXML(); - return createDataTypeNamesFromXML( result, true ); + *************************************************************************/ + public Map getDataTypeNames() + throws MobyException { + String result = getDataTypeNamesAsXML(); + return createDataTypeNamesFromXML (result, true); } // - protected String getDataTypeNamesAsXML() throws MobyException { - return ( String ) doCall( "retrieveObjectNames", new Object[] {} ); + protected String getDataTypeNamesAsXML() + throws MobyException { + return (String)doCall ("retrieveObjectNames", + new Object[] {}); } // if onlyNames == true - // Map: data type name -> description (String) + // Map: data type name -> description (String) // else - // Map: data type name -> MobyDataType[] - // (filled with name, description, and lsid) - protected Map createDataTypeNamesFromXML( String result, boolean onlyNames ) throws MobyException { - - // parse returned XML - Map results = new TreeMap( getStringComparator() ); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Object" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String name = elem.getAttribute( "name" ); - if ( name == null ) continue; // ignore no-named data types - String desc = ""; - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "Description" ) ) { - desc = getFirstValue( children.item( j ) ); - break; - } - } - if ( onlyNames ) { - results.put( name, desc ); - } - else { - MobyDataType dt = new MobyDataType( name ); - dt.setDescription( desc ); - dt.setLSID( elem.getAttribute( "lsid" ) ); - results.put( name, dt ); - } + // Map: data type name -> MobyDataType[] + // (filled with name, description, and lsid) + protected Map createDataTypeNamesFromXML (String result, + boolean onlyNames) + throws MobyException { + + // parse returned XML + Map results = new TreeMap (getStringComparator()); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Object"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String name = elem.getAttribute ("name"); + if (name == null) + continue; // ignore no-named data types + String desc = ""; + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("Description")) { + desc = getFirstValue (children.item (j)); + break; } - return results; + } + if (onlyNames) { + results.put (name, desc); + } else { + MobyDataType dt = new MobyDataType (name); + dt.setDescription (desc); + dt.setLSID (elem.getAttribute ("lsid")); + results.put (name, dt); + } + } + return results; } - /******************************************************************************************************************* + + /************************************************************************** * Parses and imports the following XML. An example: - * + * *
                * <retrieveObjectDefinition>
          -     *   <objectType lsid="...">go_term</objectType>
          +     *   <objectType lsid="...">go_term</objectType>
                *   <Description><![CDATA[A very lightweight object holding a GO term name and its definition]]></Description>
                *   <authURI>http://www.illuminae.com</authURI>
                *   <contactEmail>markw at illuminae.com</contactEmail>
          @@ -1006,448 +1071,529 @@
                *   </Relationship>
                * </retrieveObjectDefinition>
                * 
          - ******************************************************************************************************************/ - public MobyDataType getDataType( String dataTypeName ) throws MobyException, NoSuccessException { - - String result = getDataTypeAsXML( dataTypeName ); - return createDataTypeFromXML( result, dataTypeName ); - } - - public MobyDataType[] getDataTypes() throws MobyException, NoSuccessException { - Map< String, String > datatypeMap = getDataTypeNames(); - MobyDataType[] datatypes = new MobyDataType[ datatypeMap.size() ]; - int i = 0; - for ( String dataTypeName : datatypeMap.keySet() ) { - datatypes[ i++ ] = getDataType( dataTypeName ); - } - return datatypes; - } - - protected String getDataTypeAsXML( String dataTypeName ) throws MobyException, NoSuccessException { - - return ( String ) doCall( "retrieveObjectDefinition", new Object[] { "" - + "" + dataTypeName + "" + "" } ); - } - - protected MobyDataType createDataTypeFromXML( String xmlSource, String dataTypeName ) throws MobyException, - NoSuccessException { - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( xmlSource.getBytes() ) ); - NodeList list = document.getElementsByTagName( "retrieveObjectDefinition" ); - if ( list == null || list.getLength() == 0 ) - throw new NoSuccessException( "Data Type name was not found.", dataTypeName ); - MobyDataType data = null; - Element elem = ( Element ) list.item( 0 ); - NodeList children = elem.getChildNodes(); - - // first find the "real" (LSID-ized) data type name - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "objectType" ) ) { - data = new MobyDataType( getFirstValue( children.item( j ) ) ); - data.setLSID( ( ( Element ) children.item( j ) ).getAttribute( "lsid" ) ); - break; - } - } - - // if not found (unprobable) use the name given by the caller - if ( data == null ) data = new MobyDataType( dataTypeName ); - - // now fill the data type object with the rest of attributes - for ( int j = 0; j < children.getLength(); j++ ) { - String nodeName = children.item( j ).getNodeName(); - if ( nodeName.equals( "Description" ) ) { - data.setDescription( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "authURI" ) ) { - data.setAuthority( getFirstValue( children.item( j ) ) ); + *************************************************************************/ + public MobyDataType getDataType (String dataTypeName) + throws MobyException, NoSuccessException { + + String result = getDataTypeAsXML (dataTypeName); + return createDataTypeFromXML (result, dataTypeName); + } + + public MobyDataType[] getDataTypes() + throws MobyException, NoSuccessException { + Map datatypeMap = getDataTypeNames(); + MobyDataType[] datatypes = new MobyDataType[datatypeMap.size()]; + int i = 0; + for(String dataTypeName: datatypeMap.keySet()){ + datatypes[i++] = getDataType(dataTypeName); + } + return datatypes; + } + + protected String getDataTypeAsXML (String dataTypeName) + throws MobyException, NoSuccessException { + + return (String)doCall ("retrieveObjectDefinition", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + }); + } + + protected MobyDataType createDataTypeFromXML (String xmlSource, String dataTypeName) + throws MobyException, NoSuccessException { + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (xmlSource.getBytes())); + NodeList list = document.getElementsByTagName ("retrieveObjectDefinition"); + if (list == null || list.getLength() == 0) + throw new NoSuccessException ("Data Type name was not found.", + dataTypeName); + MobyDataType data = null; + Element elem = (Element)list.item (0); + NodeList children = elem.getChildNodes(); + + // first find the "real" (LSID-ized) data type name + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("objectType")) { + data = new MobyDataType (getFirstValue (children.item (j))); + data.setLSID ( ((Element)children.item (j) ).getAttribute ("lsid")); + break; + } + } + + // if not found (unprobable) use the name given by the caller + if (data == null) + data = new MobyDataType (dataTypeName); + + // now fill the data type object with the rest of attributes + for (int j = 0; j < children.getLength(); j++) { + String nodeName = children.item (j).getNodeName(); + if (nodeName.equals ("Description")) { + data.setDescription (getFirstValue (children.item (j))); + } else if (nodeName.equals ("authURI")) { + data.setAuthority (getFirstValue (children.item (j))); + } else if (nodeName.equals ("contactEmail")) { + data.setEmailContact (getFirstValue (children.item (j))); + } else if (nodeName.equals ("Relationship")) { + String relationshipType = ((Element)children.item (j)).getAttribute ("relationshipType"); + if (relationshipType.endsWith ("isa")) { + + NodeList parents = children.item (j).getChildNodes(); + for (int k = 0; k < parents.getLength(); k++) { + if (parents.item (k).getNodeName().equals ("objectType")) { + data.addParentName (getFirstValue (parents.item (k))); + } + } + } else if (relationshipType.endsWith ("hasa")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + getFirstValue (belows.item (k)), + Central.iHASA ); + } + } + } else if (relationshipType.endsWith ("has")) { + + NodeList belows = children.item (j).getChildNodes(); + for (int k = 0; k < belows.getLength(); k++) { + if (belows.item (k).getNodeName().equals ("objectType")) { + data.addChild ( ((Element)belows.item (k)).getAttribute ("articleName"), + belows.item (k).getFirstChild().getNodeValue(), + Central.iHAS ); } - else if ( nodeName.equals( "contactEmail" ) ) { - data.setEmailContact( getFirstValue( children.item( j ) ) ); - } - else if ( nodeName.equals( "Relationship" ) ) { - String relationshipType = ( ( Element ) children.item( j ) ).getAttribute( "relationshipType" ); - if ( relationshipType.endsWith( "isa" ) ) { - - NodeList parents = children.item( j ).getChildNodes(); - for ( int k = 0; k < parents.getLength(); k++ ) { - if ( parents.item( k ).getNodeName().equals( "objectType" ) ) { - data.addParentName( getFirstValue( parents.item( k ) ) ); - } - } - } - else if ( relationshipType.endsWith( "hasa" ) ) { - - NodeList belows = children.item( j ).getChildNodes(); - for ( int k = 0; k < belows.getLength(); k++ ) { - if ( belows.item( k ).getNodeName().equals( "objectType" ) ) { - data.addChild( ( ( Element ) belows.item( k ) ).getAttribute( "articleName" ), - getFirstValue( belows.item( k ) ), Central.iHASA ); - } - } - } - else if ( relationshipType.endsWith( "has" ) ) { - - NodeList belows = children.item( j ).getChildNodes(); - for ( int k = 0; k < belows.getLength(); k++ ) { - if ( belows.item( k ).getNodeName().equals( "objectType" ) ) { - data.addChild( ( ( Element ) belows.item( k ) ).getAttribute( "articleName" ), belows.item( - k ).getFirstChild().getNodeValue(), Central.iHAS ); - } - } - } } } - return data; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getServiceWSDL( String serviceName ) throws MobyException, NoSuccessException { - - Map names = getServiceNames(); - - for ( Iterator it = names.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = ( Map.Entry ) it.next(); - if ( ( ( String ) entry.getKey() ).equals( serviceName ) ) - return getServiceWSDL( serviceName, ( String ) entry.getValue() ); - } - - throw new NoSuccessException( "Service not found.", serviceName ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getServiceWSDL( String serviceName, String authority ) throws MobyException, NoSuccessException { - - String cacheId = "getServiceWSDL" + serviceName + ":" + authority; - String cachedResults = ( String ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "retrieveService", - new Object[] { "" + "" + "" } ); - - // parse returned XML - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - Element service = document.getDocumentElement(); - Node wsdl = service.getFirstChild(); - if ( wsdl == null ) - throw new NoSuccessException( "Service not found OR WSDL is not available.", serviceName + " (" + authority - + ")" ); - - String results = wsdl.getNodeValue(); - setContents( cacheId, results ); - return results; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterDataTypeXML( MobyDataType dataType ) { - - // build the ISA tag (expressing hierarchy of data types) - String[] names = dataType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < names.length; i++ ) { - buf.append( "" ); - buf.append( names[ i ] ); - buf.append( "" ); - buf.append( "\n" ); - } - - // build the HASA/HAS tags (expressing containments of data types) - MobyRelationship[] children = dataType.getChildren(); - StringBuffer buf2 = new StringBuffer(); // for HASA - StringBuffer buf3 = new StringBuffer(); // for HAS - for ( int i = 0; i < children.length; i++ ) { - if ( children[ i ].getRelationshipType() == Central.iHASA ) { - buf2.append( "" ); - buf2.append( children[ i ].getDataTypeName() ); - buf2.append( "" ); - } - else if ( children[ i ].getRelationshipType() == Central.iHAS ) { - buf3.append( "" ); - buf3.append( children[ i ].getDataTypeName() ); - buf3.append( "" ); - } } - - return "" + "" + dataType.getName() + "" - + "" + "" - + "" + new String( buf ) + "" - + "" + new String( buf2 ) + "" - + "" + new String( buf3 ) + "" + "" - + dataType.getAuthority() + "" + "" + dataType.getEmailContact() - + "" + ""; } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerDataType( MobyDataType dataType ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerObjectClass", new Object[] { getRegisterDataTypeXML( dataType ) } ); - dataType.setId( checkRegistration( result, dataType )[ 0 ] ); + return data; + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName) + throws MobyException, NoSuccessException { + + Map names = getServiceNames(); + + for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { + Map.Entry entry = (Map.Entry)it.next(); + if ( ((String)entry.getKey()).equals (serviceName) ) + return getServiceWSDL (serviceName, (String)entry.getValue()); + } + + throw new NoSuccessException ("Service not found.", serviceName); + } + + /************************************************************************** + * + *************************************************************************/ + public String getServiceWSDL (String serviceName, String authority) + throws MobyException, NoSuccessException { + + String cacheId = "getServiceWSDL" + serviceName + ":" + authority; + String cachedResults = (String)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("retrieveService", + new Object[] { + "" + + "" + + "" + }); + + // parse returned XML + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + Element service = document.getDocumentElement(); + Node wsdl = service.getFirstChild(); + if (wsdl == null) + throw new NoSuccessException ("Service not found OR WSDL is not available.", + serviceName + " (" + authority + ")"); + + String results = wsdl.getNodeValue(); + setContents (cacheId, results); + return results; + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterDataTypeXML (MobyDataType dataType) { + + // build the ISA tag (expressing hierarchy of data types) + String[] names = dataType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + // build the HASA/HAS tags (expressing containments of data types) + MobyRelationship[] children = dataType.getChildren(); + StringBuffer buf2 = new StringBuffer(); // for HASA + StringBuffer buf3 = new StringBuffer(); // for HAS + for (int i = 0; i < children.length; i++) { + if (children[i].getRelationshipType() == Central.iHASA) { + buf2.append (""); + buf2.append (children[i].getDataTypeName()); + buf2.append (""); + } else if (children[i].getRelationshipType() == Central.iHAS) { + buf3.append (""); + buf3.append (children[i].getDataTypeName()); + buf3.append (""); + } + } + + return + "" + + "" + dataType.getName() + "" + + "" + + "" + + "" + new String (buf) + + "" + + "" + new String (buf2) + + "" + + "" + new String (buf3) + + "" + + "" + dataType.getAuthority() + "" + + "" + dataType.getEmailContact() + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerObjectClass", + new Object[] { getRegisterDataTypeXML (dataType) }); + dataType.setId (checkRegistration (result, dataType)[0]); } - /******************************************************************************************************************* + /************************************************************************* * B - ******************************************************************************************************************/ - public void unregisterDataType( MobyDataType dataType ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterObjectClass", new Object[] { "" - + "" + dataType.getName() + "" + "" } ); - checkRegistration( result, dataType ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterServiceTypeXML( MobyServiceType serviceType ) { - - // build the ISA tag (expressing hierarchy of service types) - String[] names = serviceType.getParentNames(); - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < names.length; i++ ) { - buf.append( "" ); - buf.append( names[ i ] ); - buf.append( "" ); - buf.append( "\n" ); - } - - return "" + "" + serviceType.getName() + "" + "" - + serviceType.getEmailContact() + "" + "" + serviceType.getAuthority() - + "" + "" + "" - + "" + new String( buf ) + "" - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerServiceType( MobyServiceType serviceType ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerServiceType", - new Object[] { getRegisterServiceTypeXML( serviceType ) } ); - serviceType.setId( checkRegistration( result, serviceType )[ 0 ] ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterServiceType( MobyServiceType serviceType ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterServiceType", new Object[] { "" - + "" + serviceType.getName() + "" + "" } ); - checkRegistration( result, serviceType ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterNamespaceXML( MobyNamespace namespace ) { - return "" + "" + namespace.getName() + "" + "" - + namespace.getEmailContact() + "" + "" + namespace.getAuthority() - + "" + "" + "" - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerNamespace( MobyNamespace namespace ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "registerNamespace", new Object[] { getRegisterNamespaceXML( namespace ) } ); - namespace.setId( checkRegistration( result, namespace )[ 0 ] ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterNamespace( MobyNamespace namespace ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterNamespace", new Object[] { "" - + "" + namespace.getName() + "" + "" } ); - checkRegistration( result, namespace ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String getRegisterServiceXML( MobyService service ) { - return "" + "" + service.getCategory() + "" + "" - + service.getName() + "" + "" + service.getType() + "" - + "" + ( service.getLSID() == null ? "" : service.getLSID().trim() ) + "" - + "" + service.getAuthority() + "" + "" - + escapeXML( service.getSignatureURL() ) + "" + "" + escapeXML( service.getURL() ) - + "" + "" + service.getEmailContact() + "" - + "" + ( service.isAuthoritative() ? "1" : "0" ) + "" - + "" + "" - + buildPrimaryInputTag( service ) + buildSecondaryInputTag( service ) + buildOutputTag( service ) - + ""; - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void registerService( MobyService service ) throws MobyException, NoSuccessException, - PendingCurationException { - - String result = ( String ) doCall( "registerService", new Object[] { getRegisterServiceXML( service ) } ); - String[] registered = checkRegistration( result, service ); - service.setId( registered[ 0 ] ); - service.setRDF( registered[ 1 ] ); - String pathToRDF = service.getPathToRDF(); - if ( !pathToRDF.equals( "" ) ) { - File fileRDF = new File( pathToRDF ); - try { - PrintStream fileout = new PrintStream( new FileOutputStream( fileRDF ) ); - fileout.println( registered[ 1 ] ); - fileout.close(); - } - catch ( IOException e ) { - StringBuffer buf = new StringBuffer( 100 ); - buf.append( "Failed to save RDF in '" ); - buf.append( fileRDF.getAbsolutePath() + "'. " ); - buf.append( e.toString() ); - try { - File tmpFile = File.createTempFile( service.getName() + "-", ".rdf" ); - PrintStream fileout = new PrintStream( new FileOutputStream( tmpFile ) ); - fileout.println( registered[ 1 ] ); - fileout.close(); - buf.append( "\nReturned RDF file was therefore stored in: " ); - buf.append( tmpFile.getAbsolutePath() ); - } - catch ( IOException e2 ) { - buf.append( "\nEven saving in a temporary file failed: " ); - buf.append( e2.toString() ); - } - throw new MobyException( buf.toString() ); - } - } - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public void unregisterService( MobyService service ) throws MobyException, NoSuccessException, - PendingCurationException { - String result = ( String ) doCall( "deregisterService", new Object[] { "" + "" - + service.getAuthority() + "" + "" + service.getName() + "" - + "" } ); - checkRegistration( result, service ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( String serviceType ) throws MobyException { - if ( serviceType == null ) return new MobyService[] {}; - MobyService pattern = new MobyService( "dummy" ); - pattern.setCategory( "" ); - pattern.setType( serviceType ); - return findService( pattern, null ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( String[] keywords ) throws MobyException { - if ( keywords == null ) return new MobyService[] {}; - return findService( null, keywords ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern ) throws MobyException { - if ( pattern == null ) return new MobyService[] {}; - return findService( pattern, null ); - } - - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern, String[] keywords ) throws MobyException { - return findService( pattern, keywords, true, true ); + *************************************************************************/ + public void unregisterDataType (MobyDataType dataType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterObjectClass", + new Object[] { + "" + + "" + dataType.getName() + "" + + "" + }); + checkRegistration (result, dataType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceTypeXML (MobyServiceType serviceType) { + + // build the ISA tag (expressing hierarchy of service types) + String[] names = serviceType.getParentNames(); + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < names.length; i++) { + buf.append (""); + buf.append (names[i]); + buf.append (""); + buf.append ("\n"); + } + + return + "" + + "" + serviceType.getName() + "" + + "" + serviceType.getEmailContact() + "" + + "" + serviceType.getAuthority() + "" + + "" + + "" + + "" + new String (buf) + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerServiceType", + new Object[] { getRegisterServiceTypeXML (serviceType) }); + serviceType.setId (checkRegistration (result, serviceType)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterServiceType (MobyServiceType serviceType) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterServiceType", + new Object[] { + "" + + "" + serviceType.getName() + "" + + "" + }); + checkRegistration (result, serviceType); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterNamespaceXML (MobyNamespace namespace) { + return + "" + + "" + namespace.getName() + "" + + "" + namespace.getEmailContact() + "" + + "" + namespace.getAuthority() + "" + + "" + + "" + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("registerNamespace", + new Object[] { getRegisterNamespaceXML (namespace) }); + namespace.setId (checkRegistration (result, namespace)[0]); + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterNamespace (MobyNamespace namespace) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterNamespace", + new Object[] { + "" + + "" + namespace.getName() + "" + + "" + }); + checkRegistration (result, namespace); + } + + /************************************************************************* + * + *************************************************************************/ + public String getRegisterServiceXML (MobyService service) { + return + "" + + "" + service.getCategory() + "" + + "" + service.getName() + "" + + "" + service.getType() + "" + + "" + (service.getLSID() == null ? "" : service.getLSID().trim() )+ "" + + "" + service.getAuthority() + "" + + "" + escapeXML (service.getSignatureURL()) + "" + + "" + escapeXML (service.getURL()) + "" + + "" + service.getEmailContact() + "" + + "" + (service.isAuthoritative() ? "1" : "0") + "" + + "" + + "" + + buildPrimaryInputTag (service) + + buildSecondaryInputTag (service) + + buildOutputTag (service) + + ""; + } + + /************************************************************************* + * + *************************************************************************/ + public void registerService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + + String result = + (String)doCall ("registerService", + new Object[] { getRegisterServiceXML (service) }); + String[] registered = checkRegistration (result, service); + service.setId (registered [0]); + service.setRDF (registered [1]); + String pathToRDF = service.getPathToRDF(); + if ( ! pathToRDF.equals ("") ) { + File fileRDF = new File (pathToRDF); + try { + PrintStream fileout = new PrintStream (new FileOutputStream (fileRDF)); + fileout.println (registered [1]); + fileout.close(); + } catch (IOException e) { + StringBuffer buf = new StringBuffer (100); + buf.append ("Failed to save RDF in '"); + buf.append (fileRDF.getAbsolutePath() + "'. "); + buf.append (e.toString()); + try { + File tmpFile = File.createTempFile (service.getName() + "-", ".rdf"); + PrintStream fileout = new PrintStream (new FileOutputStream (tmpFile)); + fileout.println (registered [1]); + fileout.close(); + buf.append ("\nReturned RDF file was therefore stored in: "); + buf.append (tmpFile.getAbsolutePath()); + } catch (IOException e2) { + buf.append ("\nEven saving in a temporary file failed: "); + buf.append (e2.toString()); + } + throw new MobyException (buf.toString()); + } + } + } + + /************************************************************************* + * + *************************************************************************/ + public void unregisterService (MobyService service) + throws MobyException, NoSuccessException, PendingCurationException { + String result = + (String)doCall ("deregisterService", + new Object[] { + "" + + "" + service.getAuthority() + "" + + "" + service.getName() + "" + + "" + }); + checkRegistration (result, service); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String serviceType) + throws MobyException { + if (serviceType == null) + return new MobyService[] {}; + MobyService pattern = new MobyService ("dummy"); + pattern.setCategory (""); + pattern.setType (serviceType); + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (String[] keywords) + throws MobyException { + if (keywords == null) + return new MobyService[] {}; + return findService (null, keywords); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern) + throws MobyException { + if (pattern == null) + return new MobyService[] {}; + return findService (pattern, null); + } + + /************************************************************************** + * + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords) + throws MobyException { + return findService (pattern, keywords, true, true); } - /******************************************************************************************************************* + /************************************************************************** * All 'findService' methods end up here. - ******************************************************************************************************************/ - public MobyService[] findService( MobyService pattern, String[] keywords, boolean includeChildrenServiceTypes, - boolean includeParentDataTypes ) throws MobyException { - if ( pattern == null ) { - pattern = new MobyService( "dummy" ); - pattern.setCategory( "" ); - } + *************************************************************************/ + public MobyService[] findService (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + if (pattern == null) { + pattern = new MobyService ("dummy"); + pattern.setCategory (""); + } - String result = getServicesAsXML( pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes ); - MobyService[] services = extractServices( result ); - return services; + String result = + getServicesAsXML (pattern, keywords, includeChildrenServiceTypes, includeParentDataTypes); + MobyService[] services = extractServices (result); + return services; } // ...actually all 'findService' methods end up here - protected String getServicesAsXML( MobyService pattern, String[] keywords, boolean includeChildrenServiceTypes, - boolean includeParentDataTypes ) throws MobyException { - String[] query = new String[] { "" - + buildQueryObject( pattern, keywords, includeParentDataTypes, includeChildrenServiceTypes, false ) - + "" }; - return ( String ) doCall( "findService", query ); + protected String getServicesAsXML (MobyService pattern, String[] keywords, + boolean includeChildrenServiceTypes, + boolean includeParentDataTypes) + throws MobyException { + String[] query = new String[] { + "" + + buildQueryObject (pattern, keywords, + includeParentDataTypes, + includeChildrenServiceTypes, + false) + + "" + }; + return (String)doCall ("findService", query); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public String call( String methodName, String inputXML ) throws MobyException { - Object result; - if ( inputXML == null || inputXML.equals( "" ) ) - result = doCall( methodName, new Object[] {} ); - else - result = doCall( methodName, new Object[] { inputXML } ); - return ( String ) result; + /************************************************************************** + * + *************************************************************************/ + public String call (String methodName, String inputXML) + throws MobyException { + Object result; + if (inputXML == null || inputXML.equals ("")) + result = doCall (methodName, new Object[] { }); + else + result = doCall (methodName, new Object[] { inputXML }); + return (String)result; + } + + /************************************************************************** + * + *************************************************************************/ + protected static String resultToString (Object result) + throws MobyException { + if (result == null) + throw new MobyException ("Returned result is null."); + if (result instanceof String) + return (String)result; + if (result instanceof String[]) { + String[] tmp = (String[])result; + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < tmp.length; i++) + buf.append (tmp[i]); + return new String (buf); } + if (result instanceof byte[]) + return new String ((byte[])result); - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - protected static String resultToString( Object result ) throws MobyException { - if ( result == null ) throw new MobyException( "Returned result is null." ); - if ( result instanceof String ) return ( String ) result; - if ( result instanceof String[] ) { - String[] tmp = ( String[] ) result; - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < tmp.length; i++ ) - buf.append( tmp[ i ] ); - return new String( buf ); - } - if ( result instanceof byte[] ) return new String( ( byte[] ) result ); - - throw new MobyException( "Unknown type of result: " + result.getClass().getName() ); + throw new MobyException ("Unknown type of result: " + result.getClass().getName()); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public boolean setDebug( boolean enabled ) { - boolean oldMode = debug; - debug = enabled; - return oldMode; + /************************************************************************** + * + *************************************************************************/ + public boolean setDebug (boolean enabled) { + boolean oldMode = debug; + debug = enabled; + return oldMode; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
                * <Relationships>
                *   <Relationship relationshipType='urn:lsid:biomoby.org:servicerelation:isa'>
          @@ -1456,45 +1602,55 @@
                *   </Relationship>
                * </Relationships>
                * 
          - ******************************************************************************************************************/ - public String[] getServiceTypeRelationships( String serviceTypeName, boolean expand ) throws MobyException { - String result = getServiceTypeRelationshipsAsXML( serviceTypeName, expand ); - return createServiceTypeRelationshipsFromXML( result ); + *************************************************************************/ + public String[] getServiceTypeRelationships (String serviceTypeName, + boolean expand) + throws MobyException { + String result = getServiceTypeRelationshipsAsXML (serviceTypeName, expand); + return createServiceTypeRelationshipsFromXML (result); } // - protected String getServiceTypeRelationshipsAsXML( String serviceTypeName, boolean expand ) throws MobyException { - return ( String ) doCall( "Relationships", new Object[] { "" + "" + serviceTypeName - + "" + "" + Central.ISA + "" - + "" + ( expand ? "1" : "0" ) + "" + "" } ); + protected String getServiceTypeRelationshipsAsXML (String serviceTypeName, + boolean expand) + throws MobyException { + return + (String)doCall ("Relationships", + new Object[] { + "" + + "" + serviceTypeName + "" + + "" + Central.ISA + "" + + "" + (expand ? "1" : "0") + "" + + "" + }); } // - protected String[] createServiceTypeRelationshipsFromXML( String result ) throws MobyException { + protected String[] createServiceTypeRelationshipsFromXML (String result) + throws MobyException { - // parse returned XML - Vector< String > v = new Vector< String >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "serviceType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("serviceType")) { + v.addElement (getFirstValue (children.item (j))); + } } - String[] results = new String[ v.size() ]; - v.copyInto( results ); - return results; + } + String[] results = new String [v.size()]; + v.copyInto (results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
          -     * lt;Relationships>
          +     *<Relationships>
                *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
                *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
                *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
          @@ -1503,411 +1659,431 @@
                *    <objectType>urn:lsid:biomoby.org:objectclass:string</objectType>
                *    <objectType>urn:lsid:biomoby.org:objectclass:integer</objectType>
                *  </Relationship>
          -     * lt;/Relationships>
          +     *</Relationships>
                * 
          - * - * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an attributes 'lsid' and 'articleName' in - * <objectType> element. - ******************************************************************************************************************/ - public Map getDataTypeRelationships( String dataTypeName ) throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName; - Map cachedResults = ( Map ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "Relationships", new Object[] { "" + "" - + dataTypeName + "" + "" + Central.ISA + "" - + "" + Central.HASA + "" + "" + Central.HAS - + "" + "1" + "" } ); - - // parse returned XML - Map results = new HashMap(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - String relType = elem.getAttribute( "relationshipType" ); - NodeList children = elem.getChildNodes(); - Vector< String > v = new Vector< String >(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "objectType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } - String[] names = new String[ v.size() ]; - v.copyInto( names ); - results.put( relType, names ); + * + * Added at Sun Feb 19 19:32:31 PHT 2006: it recognizes also an + * attributes 'lsid' and 'articleName' in <objectType> element. + *************************************************************************/ + public Map getDataTypeRelationships (String dataTypeName) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName; + Map cachedResults = (Map)getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + Central.ISA + "" + + "" + Central.HASA + "" + + "" + Central.HAS + "" + + "1" + + "" + }); + + // parse returned XML + Map results = new HashMap(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + String relType = elem.getAttribute ("relationshipType"); + NodeList children = elem.getChildNodes(); + Vector v = new Vector(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); + } } + String[] names = new String [v.size()]; + v.copyInto (names); + results.put (relType, names); + } - setContents( cacheId, results ); - return results; + setContents (cacheId, results); + return results; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
          -     * lt;Relationships>
          +     *<Relationships>
                *  <Relationship relationshipType='urn:lsid:biomoby.org:objectrelation:isa'>
                *    <objectType>urn:lsid:biomoby.org:objectclass:virtualsequence</objectType>
                *    <objectType>urn:lsid:biomoby.org:objectclass:object</objectType>
                *  </Relationship>
          -     * lt;/Relationships>
          +     *</Relationships>
                * 
          - ******************************************************************************************************************/ - public String[] getDataTypeRelationships( String dataTypeName, String relationshipType ) throws MobyException { - - String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; - String[] cachedResults = ( String[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "Relationships", new Object[] { "" + "" - + dataTypeName + "" + "" + relationshipType + "" - + "1" + "" } ); - - // parse returned XML - Vector< String > v = new Vector< String >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Relationship" ); - - // it should always be just one element in this list - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - NodeList children = elem.getChildNodes(); - for ( int j = 0; j < children.getLength(); j++ ) { - if ( children.item( j ).getNodeName().equals( "objectType" ) ) { - v.addElement( getFirstValue( children.item( j ) ) ); - } - } + *************************************************************************/ + public String[] getDataTypeRelationships (String dataTypeName, + String relationshipType) + throws MobyException { + + String cacheId = "getDataTypeRelationships_" + dataTypeName + ":" + relationshipType; + String[] cachedResults = (String[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = + (String)doCall ("Relationships", + new Object[] { + "" + + "" + dataTypeName + "" + + "" + relationshipType + "" + + "1" + + "" + }); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Relationship"); + + // it should always be just one element in this list + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + NodeList children = elem.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item (j).getNodeName().equals ("objectType")) { + v.addElement (getFirstValue (children.item (j))); } - String[] results = new String[ v.size() ]; - v.copyInto( results ); + } + } + String[] results = new String [v.size()]; + v.copyInto (results); - setContents( cacheId, results ); - return results; + setContents (cacheId, results); + return results; } - // /************************************************************************** - // * - // *************************************************************************/ - // public MobyRelationship[] getRelationships (String dataTypeName) - // throws MobyException { - // return null; - // } +// /************************************************************************** +// * +// *************************************************************************/ +// public MobyRelationship[] getRelationships (String dataTypeName) +// throws MobyException { +// return null; +// } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ + + /************************************************************************** + * + *************************************************************************/ public String getRegistryEndpoint() { - return endpoint.toString(); + return endpoint.toString(); } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ + /************************************************************************** + * + *************************************************************************/ public String getRegistryNamespace() { - return uri; + return uri; } - /******************************************************************************************************************* + /************************************************************************** * Parses and imports the following XML. - * *
                * <resourceURLs>
          -     *   <Resource name="Service"         url="..." />
          -     *   <Resource name="Object"          url="..." />
          -     *   <Resource name="Namespace"       url="..." />
          -     *   <Resource name="ServiceInstance" url="..." />
          -     *   <Resource name="Full"            url="..." />
          +     *   <Resource name="Service"         url="..." />
          +     *   <Resource name="Object"          url="..." />
          +     *   <Resource name="Namespace"       url="..." />
          +     *   <Resource name="ServiceInstance" url="..." />
          +     *   <Resource name="Full"            url="..." />
                * </resourceURLs>
                * 
          - ******************************************************************************************************************/ - public MobyResourceRef[] getResourceRefs() throws MobyException { - - String cacheId = "retrieveResourceURLs"; - MobyResourceRef[] cachedResults = ( MobyResourceRef[] ) getContents( cacheId ); - if ( cachedResults != null ) return cachedResults; - - String result = ( String ) doCall( "retrieveResourceURLs", new Object[] {} ); - - // parse returned XML - Vector< MobyResourceRef > v = new Vector< MobyResourceRef >(); - Document document = loadDocument( new ByteArrayInputStream( result.getBytes() ) ); - NodeList list = document.getElementsByTagName( "Resource" ); - for ( int i = 0; i < list.getLength(); i++ ) { - Element elem = ( Element ) list.item( i ); - try { - v.addElement( new MobyResourceRef( elem.getAttribute( "name" ), new URL( ( String ) elem - .getAttribute( "url" ) ), elem.getAttribute( "type" ) ) ); - } - catch ( MalformedURLException e2 ) { - if ( debug ) System.err.println( "Bad URL: " + elem.getAttribute( "url" ) ); - } + *************************************************************************/ + public MobyResourceRef[] getResourceRefs() + throws MobyException { + + String cacheId = "retrieveResourceURLs"; + MobyResourceRef[] cachedResults = (MobyResourceRef[])getContents (cacheId); + if (cachedResults != null) + return cachedResults; + + String result = (String)doCall ("retrieveResourceURLs", + new Object[] {}); + + // parse returned XML + Vector v = new Vector(); + Document document = loadDocument (new ByteArrayInputStream (result.getBytes())); + NodeList list = document.getElementsByTagName ("Resource"); + for (int i = 0; i < list.getLength(); i++) { + Element elem = (Element)list.item (i); + try { + v.addElement + (new MobyResourceRef (elem.getAttribute ("name"), + new URL ((String)elem.getAttribute ("url")), + elem.getAttribute ("type"))); + } catch (MalformedURLException e2) { + if (debug) + System.err.println ("Bad URL: " + elem.getAttribute ("url")); } + } - MobyResourceRef[] results = new MobyResourceRef[ v.size() ]; - v.copyInto( results ); + MobyResourceRef[] results = new MobyResourceRef [v.size()]; + v.copyInto (results); - // Add this data to the cache in case we get called again - setContents( cacheId, results ); + // Add this data to the cache in case we get called again + setContents (cacheId, results); - return results; + return results; } - /******************************************************************************************************************* - * - ******************************************************************************************************************/ - public InputStream getResource( String resourceName ) throws MobyException { + /************************************************************************** + * + *************************************************************************/ + public InputStream getResource (String resourceName) + throws MobyException { - MobyResourceRef[] resourceRefs = getResourceRefs(); - for ( int i = 0; i < resourceRefs.length; i++ ) { - if ( resourceName.equalsIgnoreCase( resourceRefs[ i ].getResourceName() ) ) { - return Utils.getInputStream( resourceRefs[ i ].getResourceLocation() ); - } + MobyResourceRef[] resourceRefs = getResourceRefs(); + for (int i = 0; i < resourceRefs.length; i++) { + if (resourceName.equalsIgnoreCase (resourceRefs[i].getResourceName())) { + return Utils.getInputStream (resourceRefs[i].getResourceLocation()); } - throw new MobyException( "No resource found for '" + resourceName + "'." ); + } + throw new MobyException ("No resource found for '" + resourceName + "'."); } - /******************************************************************************************************************* - * Return a case-insensitive comparator of Strings. It is used to create various TreeMaps where keys are strings. - ******************************************************************************************************************/ + /************************************************************************** + * Return a case-insensitive comparator of Strings. It is used to + * create various TreeMaps where keys are strings. + *************************************************************************/ protected static Comparator getStringComparator() { - return new Comparator() { - public int compare( Object o1, Object o2 ) { - return ( ( String ) o1 ).compareToIgnoreCase( ( String ) o2 ); - } + return new Comparator() { + public int compare (Object o1, Object o2) { + return ((String)o1).compareToIgnoreCase ((String)o2); + } }; } - - // cache URL/URI so we only check once + + // cache URL/URI so we only check once private static String CHECKED_URL = null; private static String CHECKED_URI = null; - + /** - * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared class hierarchy - * that implicitly check the registry will use the same cache. Otherwise, methods such as - * MobyNamespace.getNamespace() must be passed a Central object parameter as well. - * + * Using this method to get a Central object will ensure that other parts of the org.biomoby.shared + * class hierarchy that implicitly check the registry will use the same cache. Otherwise, methods + * such as MobyNamespace.getNamespace() must be passed a Central object parameter as well. + * * @return a CentralImpl using the default Central URI, and currently a class implementing a caching mechanism */ - public static CentralImpl getDefaultCentral() throws MobyException { - return getDefaultCentral( null ); + public static CentralImpl getDefaultCentral() throws MobyException{ + return getDefaultCentral(null); } - public static CentralImpl getDefaultCentral( Registry reg ) throws MobyException { - if ( reg == null && defaultCentrals.containsKey( "" ) ) { - return defaultCentrals.get( "" ); - } - else if ( reg != null && defaultCentrals.containsKey( reg.getEndpoint() ) ) { - return defaultCentrals.get( reg.getEndpoint() ); - } + public static CentralImpl getDefaultCentral(Registry reg) throws MobyException{ + if(reg == null && defaultCentrals.containsKey("")){ + return defaultCentrals.get(""); + } + else if(reg != null && defaultCentrals.containsKey(reg.getEndpoint())){ + return defaultCentrals.get(reg.getEndpoint()); + } - String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - URL resURL = classLoader.getResource( "META-INF/" + CENTRAL_IMPL_RESOURCE_NAME ); - if ( resURL != null ) { - System.err.println( "Loading " + resURL ); - try { - LineNumberReader reader = new LineNumberReader( new InputStreamReader( resURL.openStream() ) ); - for ( String line = reader.readLine(); line != null; line = reader.readLine() ) { - if ( !line.trim().startsWith( "#" ) ) { - className = line.trim(); - break; - } - } - } - catch ( Exception e ) { - logger.log( Level.WARNING, "Error reading " + resURL, e ); + String className = DEFAULT_CENTRAL_IMPL_CLASSNAME; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + URL resURL = classLoader.getResource("META-INF/"+CENTRAL_IMPL_RESOURCE_NAME); + if(resURL != null){ + System.err.println("Loading "+resURL); + try{ + LineNumberReader reader = new LineNumberReader(new InputStreamReader(resURL.openStream())); + for(String line = reader.readLine(); line != null; line = reader.readLine()){ + if(!line.trim().startsWith("#")){ + className = line.trim(); + break; } } - try { - System.err.println( "Central class is " + className ); - Class clazz = Class.forName( className ); - if ( reg == null ) { // should use default nullary c-tor - defaultCentrals.put( "", ( CentralImpl ) clazz.newInstance() ); - } - else { // should have (String endpoint, String namespace) c-tor - for ( Constructor ctor : clazz.getDeclaredConstructors() ) { - Class[] params = ctor.getParameterTypes(); - if ( params.length == 2 && params[ 0 ].getName().equals( "java.lang.String" ) - && params[ 1 ].getName().equals( "java.lang.String" ) ) { - defaultCentrals.put( reg.getEndpoint(), ( CentralImpl ) ctor.newInstance( reg.getEndpoint(), - reg.getNamespace() ) ); - break; - } - } - if ( !defaultCentrals.containsKey( reg.getEndpoint() ) ) { - logger.log( Level.WARNING, "Could not find required (String endpoint, String namespace)" - + "constructor for class " + className ); - } - } + } catch(Exception e){ + logger.log(Level.WARNING, + "Error reading " + resURL, + e); } - catch ( Exception e ) { - logger.log( Level.WARNING, "Could not load class " + className, e ); - if ( reg == null ) { - defaultCentrals.put( "", new CentralImpl() ); // fallback to this class, no caching, etc. - } - else { - defaultCentrals.put( reg.getEndpoint(), new CentralImpl( reg.getEndpoint(), reg.getNamespace() ) ); + } + try{ + System.err.println("Central class is "+className); + Class clazz = Class.forName(className); + if(reg == null){ // should use default nullary c-tor + defaultCentrals.put("", (CentralImpl) clazz.newInstance()); + } + else{ // should have (String endpoint, String namespace) c-tor + for(Constructor ctor: clazz.getDeclaredConstructors()){ + Class[] params = ctor.getParameterTypes(); + if(params.length == 2 && params[0].getName().equals("java.lang.String") && + params[1].getName().equals("java.lang.String") ){ + defaultCentrals.put(reg.getEndpoint(), + (CentralImpl) ctor.newInstance(reg.getEndpoint(), reg.getNamespace())); + break; } } + if(!defaultCentrals.containsKey(reg.getEndpoint())){ + logger.log(Level.WARNING, + "Could not find required (String endpoint, String namespace)" + + "constructor for class " + className); + } + } + } catch(Exception e){ + logger.log(Level.WARNING, + "Could not load class " + className, + e); + if(reg == null){ + defaultCentrals.put("", new CentralImpl()); //fallback to this class, no caching, etc. + } + else{ + defaultCentrals.put(reg.getEndpoint(), + new CentralImpl(reg.getEndpoint(), reg.getNamespace())); + } + } - return defaultCentrals.get( reg == null ? "" : reg.getEndpoint() ); + return defaultCentrals.get(reg == null ? "" : reg.getEndpoint()); } /** * - * @return a String representing the Default mobycentral endpoint. If the system property 'moby.check.default' - * exists and is set to true, then the URL http://biomoby.org/mobycentral is queried and the default central - * endpoint is returned, otherwise DEFAULT_ENDPOINT is returned. + * @return a String representing the Default mobycentral endpoint. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central endpoint is returned, otherwise DEFAULT_ENDPOINT + * is returned. */ public static String getDefaultURL() { - boolean check = false; + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + + if (check) { + // return the last checked url if we have done this before + if (CHECKED_URL != null && CHECKED_URL.trim() != "") { + return CHECKED_URL; + } + + // create a HttpClient object + HttpClient client = new HttpClient(); + // set up the Head method + HeadMethod method = new HeadMethod("http://biomoby.org/mobycentral"); + // do not follow redirects or we will get a 411 error + method.setFollowRedirects(false); + // retry 3 times + method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler(3, false)); + // set the user agent ... should probably make this something more reasonable + method.getParams().setParameter(HttpMethodParams.USER_AGENT,"jMoby/1.0"); try { - check = Boolean.getBoolean( "moby.check.default" ); - } - catch ( Exception e ) { - - } + // Execute the method. + int statusCode = client.executeMethod(method); - if ( check ) { - // return the last checked url if we have done this before - if ( CHECKED_URL != null && CHECKED_URL.trim() != "" ) { - return CHECKED_URL; - } - - // create a HttpClient object - HttpClient client = new HttpClient(); - // set up the Head method - HeadMethod method = new HeadMethod( "http://biomoby.org/mobycentral" ); - // do not follow redirects or we will get a 411 error - method.setFollowRedirects( false ); - // retry 3 times - method.getParams().setParameter( HttpMethodParams.RETRY_HANDLER, - new DefaultHttpMethodRetryHandler( 3, false ) ); - // set the user agent ... should probably make this something more reasonable - method.getParams().setParameter( HttpMethodParams.USER_AGENT, "jMoby/1.0" ); + if (statusCode != HttpStatus.SC_MOVED_PERMANENTLY) { + System.err.println("Method failed: " + + method.getStatusLine()); + } else { try { - // Execute the method. - int statusCode = client.executeMethod( method ); - - if ( statusCode != HttpStatus.SC_MOVED_PERMANENTLY ) { - System.err.println( "Method failed: " + method.getStatusLine() ); - } - else { - try { - String location = method.getResponseHeader( "location" ).getValue(); - CHECKED_URL = location; - try { - CHECKED_URI = "http://" + ( new URL( CHECKED_URL ).getAuthority() ) + "/MOBY/Central"; - } - catch ( MalformedURLException murle ) { - CHECKED_URI = DEFAULT_NAMESPACE; - } - return CHECKED_URL; - } - catch ( NullPointerException npe ) { - return DEFAULT_ENDPOINT; - } - } - } - catch ( HttpException e ) { - System.err.println( "Fatal protocol violation: " + e.getMessage() ); - e.printStackTrace(); - } - catch ( IOException e ) { - System.err.println( "Fatal transport error: " + e.getMessage() ); - e.printStackTrace(); - } - finally { - // Release the connection. - method.releaseConnection(); + String location = method.getResponseHeader("location").getValue(); + CHECKED_URL = location; + try { + CHECKED_URI = "http://" + (new URL(CHECKED_URL).getAuthority()) + "/MOBY/Central"; + } catch (MalformedURLException murle ) { + CHECKED_URI = DEFAULT_NAMESPACE; } - - } - else { + return CHECKED_URL; + } catch (NullPointerException npe) { return DEFAULT_ENDPOINT; + } } + } catch (HttpException e) { + System.err.println("Fatal protocol violation: " + + e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + System.err.println("Fatal transport error: " + e.getMessage()); + e.printStackTrace(); + } finally { + // Release the connection. + method.releaseConnection(); + } + + } else { return DEFAULT_ENDPOINT; } - + return DEFAULT_ENDPOINT; + } + /** * - * @return a String representing the default mobycentral uri. If the system property 'moby.check.default' exists and - * is set to true, then the URL http://biomoby.org/mobycentral is queried and the default central namespace - * is returned, otherwise DEFAULT_NAMESPACE is returned. + * @return a String representing the default mobycentral uri. If the + * system property 'moby.check.default' exists and is set to true, + * then the URL http://biomoby.org/mobycentral is queried and the + * default central namespace is returned, otherwise DEFAULT_NAMESPACE + * is returned. */ public static String getDefaultURI() { - boolean check = false; - try { - check = Boolean.getBoolean( "moby.check.default" ); - } - catch ( Exception e ) { - - } - if ( check ) { - if ( CHECKED_URI != null && CHECKED_URI.trim() != "" ) { - return CHECKED_URI; - } - // need to check ... - getDefaultURL(); - return CHECKED_URI; - } - else { - return DEFAULT_NAMESPACE; - } - } - - /******************************************************************************************************************* - * Convert non-suitable characters in a XML string into their entity references. - *

          - * + boolean check = false; + try { + check = Boolean.getBoolean("moby.check.default"); + } catch (Exception e) { + + } + if (check) { + if (CHECKED_URI != null && CHECKED_URI.trim() != "") { + return CHECKED_URI; + } + // need to check ... + getDefaultURL(); + return CHECKED_URI; + } else { + return DEFAULT_NAMESPACE; + } + } + /************************************************************************** + * Convert non-suitable characters in a XML string into their + * entity references.

          + * * Adapted from jDom. - * - * @param str - * input to be converted - * @return If there were any non-suitable characters, return a new string with those characters escaped, otherwise - * return the unmodified input string - * - ******************************************************************************************************************/ - public String escapeXML( String str ) { + * + * @param str input to be converted + * @return If there were any non-suitable characters, return a new + * string with those characters escaped, otherwise return the + * unmodified input string + * + *************************************************************************/ + public String escapeXML (String str) { StringBuffer buffer = null; char ch; String entity; - for ( int i = 0; i < str.length(); i++ ) { - ch = str.charAt( i ); - switch ( ch ) { - case '<': - entity = "<"; - break; - case '>': - entity = ">"; - break; - case '&': - entity = "&"; - break; - default: - entity = null; - break; + for (int i = 0; i < str.length(); i++) { + ch = str.charAt (i); + switch (ch) { + case '<' : + entity = "<"; + break; + case '>' : + entity = ">"; + break; + case '&' : + entity = "&"; + break; + default : + entity = null; + break; } - if ( buffer == null ) { - if ( entity != null ) { + if (buffer == null) { + if (entity != null) { // An entity occurred, so we'll have to use StringBuffer // (allocate room for it plus a few more entities). - buffer = new StringBuffer( str.length() + 20 ); + buffer = new StringBuffer (str.length() + 20); // Copy previous skipped characters and fall through // to pickup current character - buffer.append( str.substring( 0, i ) ); - buffer.append( entity ); - } - } - else { - if ( entity == null ) { - buffer.append( ch ); + buffer.append (str.substring (0, i)); + buffer.append (entity); } - else { - buffer.append( entity ); + } else { + if (entity == null) { + buffer.append (ch); + } else { + buffer.append (entity); } } } @@ -1915,43 +2091,49 @@ // If there were any entities, return the escaped characters // that we put in the StringBuffer. Otherwise, just return // the unmodified input string. - return ( buffer == null ) ? str : buffer.toString(); + return (buffer == null) ? str : buffer.toString(); } - /******************************************************************************************************************* + /************************************************************************* * Format an exception. - ******************************************************************************************************************/ - public static String formatFault( AxisFault e, String endpoint, QName method ) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - formatFault( e, new PrintStream( baos ), endpoint, method ); - return baos.toString(); + *************************************************************************/ + public static String formatFault (AxisFault e, String endpoint, QName method) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + formatFault (e, new PrintStream (baos), endpoint, method); + return baos.toString(); } - /******************************************************************************************************************* + /************************************************************************* * Format an exception. - ******************************************************************************************************************/ - public static void formatFault( AxisFault e, PrintStream out, String endpoint, QName method ) { - - out.println( "===ERROR===" ); - out.println( "Fault details:" ); - // for some obvious errors I do not print all details (with a lenghty trace stack) - String faultString = e.getFaultString(); - if ( ( !faultString.startsWith( "java.net.ConnectException" ) ) - && ( faultString.indexOf( "Could not find class for the service named:" ) == -1 ) ) { - org.w3c.dom.Element[] details = e.getFaultDetails(); - for ( int i = 0; i < details.length; i++ ) { - String s = details[ i ].toString().replaceAll( "<", "<" ); - s = s.replaceAll( ">", ">" ); - out.println( s ); - } - } - out.println( "Fault string: " + faultString ); - out.println( "Fault code: " + e.getFaultCode() ); - out.println( "Fault actor: " + e.getFaultActor() ); - if ( endpoint != null || method != null ) out.println( "When calling:" ); - if ( endpoint != null ) out.println( "\t" + endpoint ); - if ( method != null ) out.println( "\t" + method ); - out.println( "===========" ); + *************************************************************************/ + public static void formatFault (AxisFault e, PrintStream out, + String endpoint, QName method) { + + out.println ("===ERROR==="); + out.println ("Fault details:"); + // for some obvious errors I do not print all details (with a lenghty trace stack) + String faultString = e.getFaultString(); + if ( (! faultString.startsWith ("java.net.ConnectException")) && + (faultString.indexOf ("Could not find class for the service named:") == -1) + ) { + org.w3c.dom.Element[] details = e.getFaultDetails(); + for (int i = 0; i < details.length; i++) { + String s = details[i].toString().replaceAll ("<", "<"); + s = s.replaceAll (">", ">"); + out.println (s); + } + } + out.println ("Fault string: " + faultString); + out.println ("Fault code: " + e.getFaultCode()); + out.println ("Fault actor: " + e.getFaultActor()); + if (endpoint != null || method != null) + out.println ("When calling:"); + if (endpoint != null) + out.println ("\t" + endpoint); + if (method != null) + out.println ("\t" + method); + out.println ("==========="); } + } From kawas at dev.open-bio.org Thu Dec 4 15:31:27 2008 From: kawas at dev.open-bio.org (Eddie Kawas) Date: Thu, 4 Dec 2008 10:31:27 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812041531.mB4FVRR8016254@dev.open-bio.org> kawas Thu Dec 4 10:31:27 EST 2008 Update of /home/repository/moby/moby-live/Perl/MOBY-Server In directory dev.open-bio.org:/tmp/cvs-serv16218/Perl/MOBY-Server Modified Files: MANIFEST Log Message: added share/cgi/service_unit_tester.pl to the manifest moby-live/Perl/MOBY-Server MANIFEST,1.9,1.10 =================================================================== RCS file: /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST 2008/11/20 19:40:41 1.9 +++ /home/repository/moby/moby-live/Perl/MOBY-Server/MANIFEST 2008/12/04 15:31:26 1.10 @@ -97,6 +97,7 @@ share/cgi/OntologyServer.cgi share/cgi/RESOURCES share/cgi/service_tester.pl +share/cgi/service_unit_tester.pl share/cgi/ServicePingerValidator share/cgi/ValidateService share/config/mobycentral.config.template From groscurt at dev.open-bio.org Wed Dec 17 10:21:57 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 05:21:57 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171021.mBHALvuv005113@dev.open-bio.org> groscurt Wed Dec 17 05:21:57 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test In directory dev.open-bio.org:/tmp/cvs-serv5054/src/main/de/mpg/mpiz_koeln/featureClient/test Modified Files: SimpleSingleCall.java SingleCallWithParameters.java MultiCallWithParameters.java MultiCallByDefinition.java ComplexSingleCall.java SimpleMultiCall.java SingleMultiServiceCall.java Log Message: moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test SimpleSingleCall.java,1.1,1.2 SingleCallWithParameters.java,1.1,1.2 MultiCallWithParameters.java,1.1,1.2 MultiCallByDefinition.java,1.1,1.2 ComplexSingleCall.java,1.1,1.2 SimpleMultiCall.java,1.1,1.2 SingleMultiServiceCall.java,1.1,1.2 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.MobyObject; @@ -19,7 +18,7 @@ client.setTimeout( 45 ); client.addService( "mpiz-koeln.mpg.de", "ID2IDs" ); client.setServiceInputSingleCall( "", "NP_176539.1" ); - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { Collection< MobyObject > collection = mobyServiceResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.AminoAcidSequence; @@ -38,7 +37,7 @@ client.setServiceInputSingleCall( organism, sequence, geneName ); - List< FeatureClientResult > result = client.call(); + Collection < FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { Collection< FASTA_AA > fastas = mobyServiceResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -79,7 +78,7 @@ client.addServiceInputMultiCall( "gene2", organism, sequence, geneName ); // the service is called - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // the map stores for each identifier given the list of results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -34,7 +33,7 @@ client.addServiceInputMultiCall( "AGI_LocusCode", "AT1G12000" ); // call the service, which will be found - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // as we have called the service multiple times we get back for each identifier the returned results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 10:21:56 1.2 @@ -34,7 +34,7 @@ client.setServiceInputSingleCall( sequence ); // start the call and retrieve the results - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult featureClientResult : result ) { // as the service was called once we get back the result for this service call Collection< AminoAcidSequence > sequences = featureClientResult.getSingleCallResult(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import java.util.Map; import org.biomoby.shared.MobyException; @@ -29,7 +28,7 @@ client.addServiceInputMultiCall( "GO", "0004396" ); // call the service - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // the map stores for each id of the input object a list of results =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 10:21:56 1.2 @@ -1,7 +1,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.MobyService; @@ -27,7 +26,7 @@ client.setServiceInputSingleCall( "AGI_LocusCode", "AT1G12000" ); // call the service - List< FeatureClientResult > result = client.call(); + Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { // you can get which service returned the current result From groscurt at dev.open-bio.org Wed Dec 17 14:07:17 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:07:17 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171407.mBHE7H6U005665@dev.open-bio.org> groscurt Wed Dec 17 09:07:16 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared In directory dev.open-bio.org:/tmp/cvs-serv5630/src/main/org/biomoby/shared Modified Files: MobyService.java Log Message: added hashCode method, based on the uniquename as used in the equals method moby-live/Java/src/main/org/biomoby/shared MobyService.java,1.25,1.26 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java 2008/10/21 16:38:44 1.25 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/MobyService.java 2008/12/17 14:07:16 1.26 @@ -102,6 +102,10 @@ if (obj == null) return false; return getUniqueName().equals ( ((MobyService)obj).getUniqueName() ); } + + public int hashCode() { + return getUniqueName().hashCode(); + } /************************************************************************** * Default constructor. From groscurt at dev.open-bio.org Wed Dec 17 14:09:00 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:09:00 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171409.mBHE90wZ005705@dev.open-bio.org> groscurt Wed Dec 17 09:09:00 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/client In directory dev.open-bio.org:/tmp/cvs-serv5670/src/main/org/biomoby/client Modified Files: MobyServiceLocator.java Log Message: javadoc had a warning... moby-live/Java/src/main/org/biomoby/client MobyServiceLocator.java,1.5,1.6 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/03 15:21:13 1.5 +++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/client/MobyServiceLocator.java 2008/12/17 14:09:00 1.6 @@ -168,7 +168,7 @@ /*************************************************** * Returns true if the user AND the password is set - * @return + * @return if authentication shall be used ***************************************************/ public boolean hasAuthentication() { return user != null && password != null; From groscurt at dev.open-bio.org Wed Dec 17 14:09:54 2008 From: groscurt at dev.open-bio.org (Andreas Groscurth) Date: Wed, 17 Dec 2008 09:09:54 -0500 Subject: [MOBY-guts] biomoby commit Message-ID: <200812171409.mBHE9sdL005791@dev.open-bio.org> groscurt Wed Dec 17 09:09:54 EST 2008 Update of /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test In directory dev.open-bio.org:/tmp/cvs-serv5728/src/main/de/mpg/mpiz_koeln/featureClient/test Modified Files: SingleCallDefinition.java SingleCallWithParameters.java ComplexSingleCall.java SingleMultiServiceCall.java MultiCallWithParameters.java SimpleSingleCall.java SimpleMultiCall.java MultiCallByDefinition.java Log Message: minor changes moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test SingleCallDefinition.java,1.1,1.2 SingleCallWithParameters.java,1.2,1.3 ComplexSingleCall.java,1.2,1.3 SingleMultiServiceCall.java,1.2,1.3 MultiCallWithParameters.java,1.2,1.3 SimpleSingleCall.java,1.2,1.3 SimpleMultiCall.java,1.2,1.3 MultiCallByDefinition.java,1.2,1.3 =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java 2008/11/26 08:52:20 1.1 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallDefinition.java 2008/12/17 14:09:54 1.2 @@ -9,14 +9,14 @@ import de.mpg.mpiz_koeln.featureClient.FeatureClientException; import de.mpg.mpiz_koeln.featureClient.FeatureClientResult; -public class SingleCallDefinition { +class SingleCallDefinition { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.addOutput( "Object", "PMID" ); client.setTimeout( 45 ); client.add2Filter( "Locus2GeneAliases", "getCor", "getGeneticElementNameByFreeText", "getGoTermAssociations", "getConservedDomainLabelFromDomainId", "ExplodeOutCrossReferences" ); - client.setServiceInputSingleCall( "", "Q9SZW4" ); + client.setSingleCallInput( "", "Q9SZW4" ); Collection< FeatureClientResult > collection = client.call(); for ( FeatureClientResult mobyServiceResult : collection ) { =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleCallWithParameters.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ import de.mpg.mpiz_koeln.featureClient.FeatureClientException; import de.mpg.mpiz_koeln.featureClient.FeatureClientResult; -public class SingleCallWithParameters { +class SingleCallWithParameters { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 120 ); @@ -35,7 +35,7 @@ geneName.setId( "my_gene" ); geneName.setName( "gene_name" ); - client.setServiceInputSingleCall( organism, sequence, geneName ); + client.setSingleCallInput( organism, sequence, geneName ); Collection < FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/ComplexSingleCall.java 2008/12/17 14:09:54 1.3 @@ -2,7 +2,6 @@ package de.mpg.mpiz_koeln.featureClient.test; import java.util.Collection; -import java.util.List; import org.biomoby.shared.MobyException; import org.biomoby.shared.datatypes.AminoAcidSequence; @@ -18,7 +17,7 @@ * This examples shows how to use the client to call a web service once which consumes a complex data type, such as * AminoAcidSequence. */ -public class ComplexSingleCall { +class ComplexSingleCall { public static void main(String[] args) throws MobyException, FeatureClientException { FeatureClient client = new FeatureClient(); // timeout of the calls is set to 45 seconds @@ -31,7 +30,7 @@ sequence.set_SequenceString( new MobyString( "MQPVKVYADRRSQPSRAVIIFCRVNQIDFEEVTVDLFKSQHLTPEFRKVNPMGQVPAIVDGR" ) ); sequence.set_Length( new MobyInteger( 50 ) ); // set the input to the client - client.setServiceInputSingleCall( sequence ); + client.setSingleCallInput( sequence ); // start the call and retrieve the results Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SingleMultiServiceCall.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ /** * This example shows how to call more service one with one input. */ -public class SingleMultiServiceCall { +class SingleMultiServiceCall { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 30 ); @@ -23,7 +23,7 @@ client.addService( "Locus2Publications" ); // set the input of the service - client.setServiceInputSingleCall( "AGI_LocusCode", "AT1G12000" ); + client.setSingleCallInput( "AGI_LocusCode", "AT1G12000" ); // call the service Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallWithParameters.java 2008/12/17 14:09:54 1.3 @@ -18,7 +18,7 @@ * This example shows how to call a service multiple times which consumes more than one input. It also shows the mixture * of a simple object input and a complex data type input. */ -public class MultiCallWithParameters { +class MultiCallWithParameters { public static void main( String[] args ) throws MobyException, FeatureClientException { FeatureClient client = new FeatureClient(); // the service might take longer, so we set the timeout to 120 seconds @@ -55,7 +55,7 @@ // adds the inputs to the client and give it an identifier, so that you are able to distinguish the several // calls later. This identifier is completely free to choice ! - client.addServiceInputMultiCall( "gene1", organism, sequence, geneName ); + client.addMultipleCallInput( "gene1", organism, sequence, geneName ); // we want to call the same service a second time so we build again some input values organism = new MobyObject(); @@ -75,7 +75,7 @@ geneName.setName( "gene_name" ); // adds the inputs to the client for the second call with a different identifier as before - client.addServiceInputMultiCall( "gene2", organism, sequence, geneName ); + client.addMultipleCallInput( "gene2", organism, sequence, geneName ); // the service is called Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleSingleCall.java 2008/12/17 14:09:54 1.3 @@ -12,12 +12,12 @@ /** * This example shows how to call a service once with a simple object input. */ -public class SimpleSingleCall { +class SimpleSingleCall { public static void main( String[] args ) throws FeatureClientException, MobyException { FeatureClient client = new FeatureClient(); client.setTimeout( 45 ); client.addService( "mpiz-koeln.mpg.de", "ID2IDs" ); - client.setServiceInputSingleCall( "", "NP_176539.1" ); + client.setSingleCallInput( "", "NP_176539.1" ); Collection< FeatureClientResult > result = client.call(); for ( FeatureClientResult mobyServiceResult : result ) { =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/SimpleMultiCall.java 2008/12/17 14:09:54 1.3 @@ -13,7 +13,7 @@ /** * This example shows how to call a web service multiple times with a simple object input. */ -public class SimpleMultiCall { +class SimpleMultiCall { public static void main( String[] args ) throws MobyException, FeatureClientException { // the client queries the default central if no given otherwise FeatureClient client = new FeatureClient(); @@ -23,9 +23,9 @@ client.addService( "mpiz-koeln.mpg.de", "get_go_information_by_go_term" ); // the three different inputs for the three service calls - client.addServiceInputMultiCall( "GO", "0044408" ); - client.addServiceInputMultiCall( "GO", "0020015" ); - client.addServiceInputMultiCall( "GO", "0004396" ); + client.addMultipleCallInput( "GO", "0044408" ); + client.addMultipleCallInput( "GO", "0020015" ); + client.addMultipleCallInput( "GO", "0004396" ); // call the service Collection< FeatureClientResult > result = client.call(); =================================================================== RCS file: /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 10:21:56 1.2 +++ /home/repository/moby/moby-live/Java/src/main/de/mpg/mpiz_koeln/featureClient/test/MultiCallByDefinition.java 2008/12/17 14:09:54 1.3 @@ -18,7 +18,7 @@ * * It also shows how to filter out services or authorities which shall be not called at all. */ -public class MultiCallByDefinition { +class MultiCallByDefinition { public static void main( String[] args ) throws MobyException, FeatureClientException { // create a client to the default moby central in calgary with a timeout of 30 seconds FeatureClient client = new FeatureClient(); @@ -28,9 +28,9 @@ // exclude services identified by service name or authority client.add2Filter( "Locus2GeneAliases", "getCor", "bioinfo.icapture.ubc.ca" ); // input for the first call -> it also defines now we search for service which consumes an AGI code - client.addServiceInputMultiCall( "AGI_LocusCode", "AT4G30110" ); + client.addMultipleCallInput( "AGI_LocusCode", "AT4G30110" ); // input for the second call - client.addServiceInputMultiCall( "AGI_LocusCode", "AT1G12000" ); + client.addMultipleCallInput( "AGI_LocusCode", "AT1G12000" ); // call the service, which will be found Collection< FeatureClientResult > result = client.call();