[MOBY-guts] biomoby commit

Mark Wilkinson mwilkinson at dev.open-bio.org
Thu Feb 8 23:03:45 UTC 2007


mwilkinson
Thu Feb  8 18:03:45 EST 2007
Update of /home/repository/moby/moby-live/Perl/MOBY
In directory dev.open-bio.org:/tmp/cvs-serv31321/MOBY

Modified Files:
	CommonSubs.pm 
Log Message:
significant updates to CommonSubs.  Revamp of documentation to reveal client-side functionality that hasnt been discussed anywhere else.  Added a new function (just a renamed reference to an old function) to show that the server-side parser can also be used client-side for parsing a MOBY message.  rearranged order of functions in documentation to make more sense.
moby-live/Perl/MOBY CommonSubs.pm,1.93,1.94
===================================================================
RCS file: /home/repository/moby/moby-live/Perl/MOBY/CommonSubs.pm,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -r1.93 -r1.94
--- /home/repository/moby/moby-live/Perl/MOBY/CommonSubs.pm	2007/01/30 22:50:52	1.93
+++ /home/repository/moby/moby-live/Perl/MOBY/CommonSubs.pm	2007/02/08 23:03:45	1.94
@@ -23,11 +23,58 @@
 FUNCTION WITH SERVICES THAT ARE NOT COMPLIANT WITH THE NEW API - FOR EXAMPLE
 SERVICES THAT ARE NOT USING NAMED INPUTS AND OUTPUTS!
 
-=head1 PARADIGMATIC USAGE
+=head1 COMMON USAGE EXAMPLES
 
 =head2 Client Side Paradigm
 
-not written yet
+
+The following is a generalized architecture for all
+BioMOBY services showing how to parse response messages
+using the subroutines provided in CommonSubs
+
+=head3 Services Returning Simples
+
+    my $resp = $SI->execute(XMLInputList => \@input_data);
+    
+    my $responses = serviceResponseParser($resp); # returns MOBY objects
+    foreach my $queryID(keys %$responses){
+        $this_invocation = $inputs->{$queryID};  # this is the <mobyData> block with this queryID
+        my $this_output = "";
+        
+        if (my $data = $this_invocation->{'responseArticleName'}){
+            # $data is a MOBY::Client::Simple|Collection|ParameterArticle
+            my ($namespace) = @{$data->namespaces};
+            my $id = $data->id; 
+            my $XML_LibXML = $input->XML_DOM;  # get access to the DOM 
+            my $desc = getNodeContentWithArticle($XML_LibXML, "String", "Description");
+            ###################
+            # DO SOMETHING TO RESPOSE DATA HERE
+            ###################
+        }
+        
+    }
+
+
+=head3 Services Returning Collections
+
+    my $resp = $SI->execute(XMLInputList => \@input_data);
+    
+    my $responses = serviceResponseParser($resp); # returns MOBY objects
+    foreach my $queryID(keys %$responses){  # $inputs is a hashref of $input{queryid}->{articlename} = input object
+        my $this_invocation = $inputs->{$queryID};
+        if (my $data = $this_invocation->{'responseArticleName'}){ # $input is a MOBY::Client::Simple|Collection|Parameter object
+            my $simples = $data->Simples;
+            foreach my $simple(@$simples){
+                my $id = $simple->id;
+                my $id = $simple->namespace;
+                my $XML_LibXML = $input->XML_DOM;  # get access to the DOM 
+
+            }
+        }
+    }
+
+
+
 
 =head2 Service-Side Paradigm
 
@@ -35,7 +82,7 @@
 BioMOBY services showing how to parse incoming messages
 using the subroutines provided in CommonSubs
 
-=head3 SIMPLE SERVICES
+=head3 Services Generating simple outputs
 
 sub _generic_service_name {
     my ($caller, $data) = @_; 
@@ -68,7 +115,7 @@
     return SOAP::Data->type('base64' => (responseHeader("illuminae.com") . $MOBY_RESPONSE . responseFooter));
  }
 
-=head3 COLLECTION SERVICES
+=head3 Services generating collection outputs 
 
 sub _generic_service_returning_collections {
     my($caller, $message) = @_;
@@ -169,12 +216,6 @@
 }
 
 
-=head1 AUTHORS
-
-Mark Wilkinson (markw at illuminae dot com), Pieter Neerincx, Frank Gibbons
-
-BioMOBY Project:  http://www.biomoby.org
-
 =cut
 
 package MOBY::CommonSubs;
@@ -243,32 +284,38 @@
 
 our @EXPORT_OK = (@{$EXPORT_TAGS{'all'}});
 
-=head1 PARSING MOBY SERVICE INVOCATIONS
+=head1 PARSING MOBY INPUT AND OUTPUT
 
-=head2 serviceInputParser
+=head2 serviceInputParser and serviceResponseParser
 
-B<function:> This routine will take a MOBY service invocation
-message and extract the Simple/Collection/Parameter objects out of it
+B<function:> These routines will take a Moby invocation (server side usage) or
+response (client-side usage) and extract the Simple/Collection/Parameter objects out of it
 as MOBY::Client::SimpleArticle, MOBY::Client::CollectionArticle,
 and/or MOBY::Client::SecondaryArticle objects.  The inputs are broken
-up into individual queryID's (invocations).  Each queryID is associated with
-one or more individual input articles that are required to invoke that service, and
-each input article is available by its articleName.
+up into individual queryID's.  Each queryID is associated with
+one or more individual articles, and each article is available by its articleName.
 
-B<usage:> C<my $inputs = serviceInputParser($MOBY_mssage));>
+B<usage:> C<my $inputs = serviceInputParser($MOBY_invocation_mssage));>
+B<usage:> C<my $outputs = serviceResponseParser($MOBY_response_message));>
 
 B<args:> C<$message> - this is the SOAP payload; i.e. the XML document containing the MOBY message
 
-B<returns:> C<$inputs> is a hashref with the following structure:
+B<returns:> C<$inputs> or C<$outputs> are a hashref with the following structure:
 
-   $inputs->{$queryID}->{articleName} =
+   $Xputs->{$queryID}->{articleName} =
        MOBY::Client::SimpleArticle |
        MOBY::Client::CollectionArticle |
        MOBY::Client::SecondaryArticle 
 
-See also:
+the SimpleArticle and CollectionArticle have methods to provide you with their
+objectType, their namespace and their ID.  If you want to get more out of them,
+you should retrieve the XML::LibXML DOM using the ->XML_DOM method call
+in either of those objects.  This can be passed into other CommonSubs routines
+such as getNodeContentWithArticle in order to retrieve sub-components of the
+Moby object you have in-hand.
 
 
+See also:
 
 =head3  Simples
 
@@ -289,8 +336,7 @@
             $inputs->{a1a}->{cutoff} =  $MOBY::Client::Secondary # <Parameter> block
 
 
-
-=head3            Collections 
+=head3  Collections 
 
 With inputs that have collections these are presented as a listref of
 Simple article DOM's.  So for the following message:
@@ -311,8 +357,8 @@
 
 will become
 
-            $inputs->{2b2}->{name1} $MOBY::Client::Collection, #  the <Collection> Block
-            $inputs->{2b2}->{cutoff} $MOBY::Client::Secondary, #  the <Parameter> Block
+            $inputs->{2b2}->{name1} = $MOBY::Client::Collection, #  the <Collection> Block
+            $inputs->{2b2}->{cutoff} = $MOBY::Client::Secondary, #  the <Parameter> Block
             
 
 
@@ -322,11 +368,11 @@
 sub serviceInputParser {
 	my ( $message ) = @_;    # get the incoming MOBY query XML
 	my @inputs;              # set empty response
-	my @queries = getInputs( $message );   # returns XML::LibXML nodes <mobyData>...</mobyData>
+	my @queries = _getInputs( $message );   # returns XML::LibXML nodes <mobyData>...</mobyData>
 	my %input_parameters;      # $input_parameters{$queryID} = [
 	foreach my $query ( @queries ) {
-            my $queryID =  getInputID( $query );    # get the queryID attribute of the mobyData
-            my @input_articles = getArticlesAsObjects( $query );
+            my $queryID =  _getQID( $query );    # get the queryID attribute of the mobyData
+            my @input_articles = _getArticlesAsObjects( $query );
             foreach my $article ( @input_articles ) { 
                 ${$input_parameters{$queryID}}{$article->articleName} =  $article;
             }
@@ -334,7 +380,58 @@
 	return \%input_parameters;
 }
 
+*serviceResponseParser = \&serviceInputParser;
+*serviceResponseParser = \&serviceInputParser;
+
+sub _getInputs {
+  my ( $XML ) = @_;
+  my $moby =  _string_to_DOM($XML);
+  my @queries;
+  foreach my $querytag qw(mobyData moby:mobyData )
+    {
+      my $x = $moby->getElementsByTagName( $querytag );    # get the mobyData block
+      for ( 1 .. $x->size() ) {    # there may be more than one mobyData per message
+	push @queries, $x->get_node( $_ );
+      }
+    }
+  return @queries;    # return them in the order that they were discovered.
+}
+
+
+sub _getArticlesAsObjects {
+  my ( $moby ) = @_;
+  $moby = _string_to_DOM($moby);
+  return undef unless $moby->nodeType == ELEMENT_NODE;
+  return undef
+    unless ($moby->nodeName =~ /^(moby:|)mobyData$/);
+  my @articles;
+  foreach my $child ( $moby->childNodes )
+    { # there may be more than one Simple/Collection per input; iterate over them
+      next unless $child->nodeType == ELEMENT_NODE;    # ignore whitespace
+      next
+	unless ( $child->nodeName =~ /^(moby:|)(Simple|Collection|Parameter)$/ );
+      my $object;
+      if ( $child->nodeName =~ /^(moby:|)Simple$/ ) {
+	$object = MOBY::Client::SimpleArticle->new( XML_DOM => $child );
+      } elsif ( $child->nodeName =~ /^(moby:|)Collection$/ ) {
+	$object = MOBY::Client::CollectionArticle->new( XML_DOM => $child );
+      } elsif ( $child->nodeName =~ /^(moby:|)Parameter$/ ) {
+	$object = MOBY::Client::SecondaryArticle->new( XML_DOM => $child );
+      }
+      next unless $object;
+      push @articles, $object;  # take the child elements, which are <Simple/> or <Collection/>
+    }
+  return @articles;    # return them.
+}
+
 
+sub _getQID {
+  my ( $XML ) = @_;
+  my $moby = _string_to_DOM($XML);
+  return '' unless ( $moby->nodeName =~ /^(moby:|)mobyData$/ );
+  my $qid =  _moby_getAttribute($moby, 'queryID' );
+  return defined( $qid ) ? $qid : '';
+}
 
 
 =head1 MESSAGE COMPONENT IDENTITY AND VALIDATION
@@ -735,6 +832,65 @@
 }
 
 
+=head1 Client-Side Common Subroutines
+
+These are the subroutines that will be most commonly used Client-Side for
+processing the output of a MOBY service
+
+=head2 processResponse
+
+=cut
+
+sub processResponse {
+	my ( $result ) = @_;
+	return ( [], [] ) unless $result;
+	my $moby;
+	unless ( ref( $result ) =~ /XML\:\:LibXML/ ) {
+		my $parser = XML::LibXML->new();
+		my $doc    = $parser->parse_string( $result );
+		$moby = $doc->getDocumentElement();
+	} else {
+		$moby = $result->getDocumentElement();
+	}
+	my @objects;
+	my @collections;
+	my @Xrefs;
+	my $success = 0;
+	foreach my $which ('mobyData', 'moby:mobyData') {
+		my $responses = $moby->getElementsByTagName( $which );
+		next unless $responses;
+		foreach my $n ( 1 .. ( $responses->size() ) ) {
+			my $resp = $responses->get_node( $n );
+			foreach my $response_component ( $resp->childNodes ) {
+				next unless $response_component->nodeType == ELEMENT_NODE;
+				if ( $response_component->nodeName =~ /^(moby:|)Simple$/ )
+				  {
+					foreach my $Object ( $response_component->childNodes ) {
+						next unless $Object->nodeType == ELEMENT_NODE;
+						$success = 1;
+						push @objects, $Object;
+					}
+				} elsif ( $response_component->nodeName =~ /^(moby:|)Collection$/ )
+				{
+					my @objects;
+					foreach my $simple ( $response_component->childNodes ) {
+						next unless $simple->nodeType == ELEMENT_NODE;
+						next unless ( $simple->nodeName =~ /^(moby:|)Simple$/ );
+						foreach my $Object ( $simple->childNodes ) {
+							next unless $Object->nodeType == ELEMENT_NODE;
+							$success = 1;
+							push @objects, $Object;
+						}
+					}
+					push @collections, \@objects
+					  ;  #I'm not using collections yet, so we just use Simples.
+				}
+			}
+		}
+	}
+	return ( \@collections, \@objects );
+}
+
 
 =head1 ANCILIARY ELEMENTS
 
@@ -879,16 +1035,13 @@
 }
 
 
-=head1 MISCELLANEOUS
+=head1 MISCELLANEOUS FUNCTIONS
 
 This section contains routines that didn't quite seem to fit anywhere else.
 
-=cut
-
-
 =head2 getNodeContentWithArticle
 
-<B><function:>   give me a DOM, a TagName, an articleName and I will return you the content
+B<function:>   give me a DOM, a TagName, an articleName and I will return you the content
                  of that node **as a string** (beware if there are additional XML tags in there!)
                  this is meant for MOBYesque PRIMITIVES - things like:
                  <String articleName="SequenceString">TAGCTGATCGAGCTGATGCTGA </String>
@@ -1032,24 +1185,21 @@
 }
 
 
-
-=head2 _moby_getAttributeNode, _moby_getAttribute
-
-B<function:> Perform the same task as the DOM routine
-getAttribute(Node), but check for both the prefixed and un-prefixed
-attribute name (the prefix in question being, of course,
-"moby:"). 
-
-B<usage:>
-
-  $id = _moby_getAttribute($xml_libxml, "id");
-
-where C<id> is an attribute in the XML block given as C<$xml_libxml>
-
-B<notes:> This function is intended for use internal to this package
-only. It's not exported.
-
-=cut
+#B<function:> Perform the same task as the DOM routine
+#getAttribute(Node), but check for both the prefixed and un-prefixed
+#attribute name (the prefix in question being, of course,
+#"moby:"). 
+#
+#B<usage:>
+#
+#  $id = _moby_getAttribute($xml_libxml, "id");
+#
+#where C<id> is an attribute in the XML block given as C<$xml_libxml>
+#
+#B<notes:> This function is intended for use internal to this package
+#only. It's not exported.
+#
+#=cut
 
 sub _moby_getAttributeNode {
   # Mimics behavior of XML::LibXML method getAttributeNode, but if the unqualified attribute cannot be found,
@@ -1214,11 +1364,30 @@
 sub _getQueryID {
   my ( $query ) = @_;
   $query = _string_to_XML($query);
-  return '' unless ( $query->nodeName =~ /^(moby:|)(queryInput|mobyData)$/ ); #Eddie - unsure
+  return '' unless ( $query->nodeName =~ /^(moby:|)mobyData$/ ); #Eddie - unsure
   return _moby_getAttribute($query, 'queryID' );
 }
 
-=head1 DEPRECATED
+
+sub _string_to_DOM {
+# Convert string to DOM.
+# If DOM passed in, just return it (i.e., this should be idempotent)
+# By Frank Gibbons, Aug. 2005
+# Utility subroutine, not for external use (no export), widely used in this package.
+  my $XML = shift;
+  my $moby;
+  return $XML if ( ref($XML) =~ /^XML\:\:LibXML/ );
+
+  my $parser = XML::LibXML->new();
+  my $doc;
+  eval { $doc = $parser->parse_string( $XML ) };
+  die("CommonSubs couldn't parse XML '$XML' because\n\t$@") if $@;
+  return $doc->getDocumentElement();
+}
+
+
+
+=head1 DEPRECATED FUNCTIONS
 
 
 =head2 genericServiceInputParser
@@ -1228,6 +1397,7 @@
 =cut
 
 sub genericServiceInputParser {
+print STDERR "the genericServiceInputParser function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
   my ( $message ) = @_;    # get the incoming MOBY query XML
   my @inputs;              # set empty response
   my @queries = getInputs( $message );   # returns XML::LibXML nodes <mobyData>...</mobyData>
@@ -1259,6 +1429,7 @@
 =cut
 
 sub complexServiceInputParser {
+print STDERR "the complexServiceInputParser function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
 	my ( $message ) = @_;    # get the incoming MOBY query XML
 	my @inputs;              # set empty response
 	my @queries = getInputs( $message );   # returns XML::LibXML nodes <mobyData>...</mobyData>
@@ -1291,6 +1462,7 @@
 =cut
 
 sub getArticles {
+print STDERR "the getArticles function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
   my ( $moby ) = @_;
   $moby = _string_to_DOM($moby);
   return undef
@@ -1316,6 +1488,7 @@
 
 
 sub getSimpleArticleIDs {
+print STDERR "the getSimpleArticleIDs function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
   my ( $desired_namespace, $input_nodes ) = @_;
   if ( $desired_namespace && !$input_nodes )
     {    # if called with ONE argument, then these are the input nodes!
@@ -1390,6 +1563,7 @@
 
 
 sub getSimpleArticleNamespaceURI {
+print STDERR "the getSimpleArticleNamespaceURI function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
 
 # pass me a <SIMPLE> input node and I will give you the lsid of the namespace of that input object
   my ( $input_node ) = @_;
@@ -1410,21 +1584,6 @@
     }
 }
 
-sub _string_to_DOM {
-# Convert string to DOM.
-# If DOM passed in, just return it (i.e., this should be idempotent)
-# By Frank Gibbons, Aug. 2005
-# Utility subroutine, not for external use (no export), widely used in this package.
-  my $XML = shift;
-  my $moby;
-  return $XML if ( ref($XML) =~ /^XML\:\:LibXML/ );
-
-  my $parser = XML::LibXML->new();
-  my $doc;
-  eval { $doc = $parser->parse_string( $XML ) };
-  die("CommonSubs couldn't parse XML '$XML' because\n\t$@") if $@;
-  return $doc->getDocumentElement();
-}
 
 =head2 getInputs
 
@@ -1433,6 +1592,7 @@
 =cut
 
 sub getInputs {
+  print STDERR "getInputs is now deprecated.  Please update your code to use the serviceInputParser\n";
   my ( $XML ) = @_;
   my $moby =  _string_to_DOM($XML);
   my @queries;
@@ -1453,6 +1613,7 @@
 =cut
 
 sub getInputID {
+    print STDERR "getInputID method is now deprecated.  Please use serviceInputParser or serviceResponseParser\n";
   my ( $XML ) = @_;
   my $moby = _string_to_DOM($XML);
   return '' unless ( $moby->nodeName =~ /^(moby:|)queryInput|mobyData$/ );
@@ -1467,6 +1628,7 @@
 =cut
 
 sub getArticlesAsObjects {
+    print STDERR "getArticlesAsObjects is now deprecated.  Please use the serviceInputParser";
   my ( $moby ) = @_;
   $moby = _string_to_DOM($moby);
   return undef unless $moby->nodeType == ELEMENT_NODE;
@@ -1499,6 +1661,7 @@
 =cut
 
 sub getCollectedSimples {
+print STDERR "the getCollectedSimples function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
   my ( $moby ) = @_;
   $moby = _string_to_DOM($moby);
   return undef unless $moby->nodeType == ELEMENT_NODE;
@@ -1520,6 +1683,8 @@
 =cut
 
 sub getInputArticles {
+print STDERR "the getInputArticles function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
+
   my ( $moby ) = @_;
   $moby = _string_to_DOM($moby);
   my $x;
@@ -1548,6 +1713,7 @@
 =cut
 
 sub extractRawContent {
+print STDERR "the extractRawContent function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
   my ( $article ) = @_;
   return "" unless ( $article || (ref( $article ) =~ /XML\:\:LibXML/) );
   my $response;
@@ -1569,6 +1735,7 @@
 =cut
 
 sub extractResponseArticles {
+print STDERR "the extractResponseArticles function of MOBY::CommonSubs is deprecated.  Please see documentation\n";
 	my ( $result ) = @_;
 	return ( [], [] ) unless $result;
 	my $moby;
@@ -1620,6 +1787,14 @@
 	return ( \@collections, \@objects );
 }
 
+
+=head1 AUTHORS
+
+Mark Wilkinson (markw at illuminae dot com), Pieter Neerincx, Frank Gibbons
+
+BioMOBY Project:  http://www.biomoby.org
+
+
 =head1 SEE ALSO
 
 




More information about the MOBY-guts mailing list