NAME

MOBYXSLT - CommonSubs using XSLT


WHY

Because huge XML message parsing with XML::Dom take too much time. xsltproc is a binary very very efficient to parse huge files.


TO BE EDITED

    Globals variables are defined in this package:
        my $TMP_DIR   = '/tmp/'; #Where your temporary files will be written
        my $XSLTPROC  = '/usr/bin/xsltproc'; #Where your xsltproc binary is located
        my $XSL_SHEET = './parseMobyMessage.xsl'; #Where your xsltproc style-sheet is located


SYNOPSIS

sub MonWebservice {

    my ($caller, $message) = (@_);
    my $moby_response;
    my $service_name = 'MonWebservice';
    #Message Parsing
    my ($service_notes,$ra_queries) = MOBYXSLT::getInputs($message); #Message Parsing
    foreach my $query (@{$ra_queries})
    {
        my $query_id = MOBYXSLT::getInputID($query);#Retrieve Query ID
            my @a_input_articles = MOBYXSLT::getArticles($query);#Retrieve articles
        my ($fasta_sequences, $fasta_namespace, $fasta_id)  = ('','','');
        foreach my $input_article (@a_input_articles)
        {
            my ($article_name, $article) = @{$input_article};
            if (MOBYXSLT::isSimpleArticle($article))
            {
                        my $object_type = MOBYXSLT::getObjectType($article);
                        if (IsTheCorrectType($object_type))
                {
                        $fasta_sequences = MOBYXSLT::getObjectContent($article);
                                    $fasta_namespace = MOBYXSLT::getObjectNamespace($article);
                                    $fasta_id = MOBYXSLT::getObjectId($article);
                }
            }
            elsif (MOBYXSLT::isCollectionArticle($article))
            {
            }
            elsif (MOBYXSLT::isSecondaryArticle($article))
            {
                    my ($param_name,$param_value) = MOBYXSLT::getParameter($article);#Retrieve parameters
            }
        }
        ######
        #What you want to do with your data
        ######
        my $cmd ="...";
        system("$cmd");
        #########
        #Send result
        #########
        $moby_response .= MOBYXSLT::simpleResponse("<$output_object_type1>$out_data</$output_object_type1>", $output_article_name1, $query_id);
     }
    return SOAP::Data->type(
         'base64' => (MOBYXSLT::responseHeader(-authority => $auth_uri, -note => "Documentation about $service_name at $url_doc"))
           . $moby_response
           . MOBYXSLT::responseFooter());

}


GLOBALS

        my $TMP_DIR   = '/tmp/'; #Where your temporary files will be written
        my $XSLTPROC  = '/usr/bin/xsltproc'; #Where your xsltproc binary is located
        my $XSL_SHEET = './parseMobyMessage.xsl'; #Where your xsltproc style-sheet is located


DESCRIPTION

        Note: many functions have same names as those from MOBY::CommonSubs

function getInputs

 Title        : getInputs
 Usage        : my ($servicenotes, $ra_queries) = getInputs($moby_message)
 Prerequisite : 
 Function     : Parse Moby message and build Perl structures to access
                for each query to their articles and objects.
 Returns      : $servicenotes: Notes returned by service provider
                $ra_queries: ARRAYREF of all queries analysed in MOBY message
 Args         : $moby_message: MOBY XML message
 Globals      : $XSLTPROC: /path/to/xsltproc binary
                $XSL_SHEET: XSL Sheet for MobyMessage Parsing
                $TMP_DIR: /where

function getInputID

 Title        : getInputID
 Usage        : my $query_id =getInputID($rh_query);
 Prerequisite : 
 Function     : Return query_id of a query from getInputs
 Returns      : $query_id
 Args         : $rh_query: query HASHREF structure from getInputs
 Globals      : none

function getArticles

 Title        : getArticles
 Usage        : my @a_input_articles =getArticles($rh_query);
 Prerequisite : 
 Function     : For a query from getInputs, retrieve list of articles 
                represented by a ARRAYREF corresponding to REF(articleName, articlePerlStructure)
 Returns      : @a_input_articles: ARRAY of articles ARRAYREF
 Args         : $rh_query: query HASHREF structure from getInputs
 Globals      : none

function getCollectedSimples

 Title        : getCollectedSimples
 Usage        : my @a_simple_articles =getCollectedSimples($rh_collection_article);
 Prerequisite : 
 Function     : For a collection query from getArticles, retrieve list of 
                simple articles
 Returns      : @a_simple_articles: ARRAY of articles HASHREF
 Args         : $rh_collection_article: collection article HASHREF structure from getArticles
 Globals      : none

function getCrossReferences

 Title        : getCrossReferences
 Usage        : my @a_crossreferences =getCrossReferences($rh_simple_article);
 Prerequisite : 
 Function     : Takes a simple article structure (from getArticles or getCollectedSimples)
                and retrieve the list of crossreferences HASHREF
 Returns      : @a_crossreferences: ARRAY of crossreferences HASHREF
 Args         : $rh_simple_article: simple article HASHREF structure from getArticles or getCollectedSimples
 Globals      : none

function getProvisionInformation

 Title        : getProvisionInformation
 Usage        : my @a_pib =getProvisionInformation($rh_simple_article);
 Prerequisite : 
 Function     : Takes a simple article structure (from getArticles or getCollectedSimples)
                and retrieve the list of Provision Information HASHREF
 Returns      : @a_pib: ARRAY of provisionInformation HASHREF
 Args         : $rh_simple_article: simple article HASHREF structure from getArticles or getCollectedSimples
 Globals      : none

function getObjectHasaElements

 Title        : getObjectHasaElements
 Usage        : my @a_hasa_elements =getObjectHasaElements($rh_simple_article);
 Prerequisite : 
 Function     : Takes a simple article structure (from getArticles or getCollectedSimples)
                and retrieve the list of "HASA" element HASHREF
 Returns      : @a_hasa_elements: ARRAY of "HASA" element HASHREF
 Args         : $rh_object: simple article HASHREF structure from getArticles or getCollectedSimples
 Globals      : none

function getObjectType

 Title        : getObjectType
 Usage        : my $object_type =getObjectType($rh_object);
 Prerequisite : 
 Function     : Returns object MOBY class/type
 Returns      : $object_type: object MOBY class/type
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getObjectName

 Title        : getObjectName
 Usage        : my $object_name =getObjectName($rh_object);
 Prerequisite : 
 Function     : Returns object moby:articleName
 Returns      : $object_name:  moby:articleName
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getObjectNamespace

 Title        : getObjectNamespace
 Usage        : my $object_namespace =getObjectNamespace($rh_object);
 Prerequisite : 
 Function     : Returns object moby:namespace
 Returns      : $object_name:  moby:namespace
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getObjectContent

 Title        : getObjectContent
 Usage        : my $object_content =getObjectContent($rh_object);
 Prerequisite : 
 Function     : Returns object content (using HTML::Entities::decode)
                Warning: this content could contain emptylines if
                        your objects contains Crossreferences or Hasa Elements ...
 Returns      : $object_content:  object content (decoded using HTML::Entities::decode)
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getObjectXML

 Title        : getObjectXML
 Usage        : my $object_xml =getObjectXML($rh_object);
 Prerequisite : 
 Function     : Returns full object moby:xml string
 Returns      : $object_xml:  object moby:xml string
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getObjectId

 Title        : getObjectId
 Usage        : my $object_id =getObjectId($rh_object);
 Prerequisite : 
 Function     : Returns object moby:id
 Returns      : $object_id:  moby:id
 Args         : $rh_object: simple article (object) HASHREF structure from getArticles,getCollectedSimples or getObjectHasaElements
 Globals      : none

function getParameter

 Title        : getParameter
 Usage        : my ($parameter_name,$parameter_value) =getParameter($rh_article);
 Prerequisite : 
 Function     : Returns parameter name an value for a Secondary aricle
 Returns      : $parameter_name
                $parameter_value
 Args         : $rh_article: secondary article HASHREF structure from getArticles
 Globals      : none

function getNodeContentWithArticle

 Title        : getNodeContentWithArticle
 Usage        : my $content = getNodeContentWithArticle($rh_query, $article_type, $article_name)
 Prerequisite : 
 Function     : inside a mobyData bloc (structured in $rh_query),
                look for an article of a defined type (Simple, Collection or Parameter).
                Foreach matching article, search for an object named $article_name.
                If found, return its content.
 Returns      : $content: content of article requested
 Args         : $rh_query: query HASHREF structure from getInputs
                $article_type: 'Simple/Collection/Parameter'
                $article_name: attribute moby:articleName 
 Globals      :

function isSimpleArticle

 Title        : isSimpleArticle
 Usage        : isSimpleArticle($rh_article)
 Prerequisite : 
 Function     : Test if an article is a moby:Simple
 Returns      : $response: BOOLEAN
 Args         : $rh_article: article HASHREF structure from getArticles
 Globals      : none

function isCollectionArticle

 Title        : isCollectionArticle
 Usage        : isCollectionArticle($rh_article)
 Prerequisite : 
 Function     : Test if an article is a moby:Collection
 Returns      : $response: BOOLEAN
 Args         : $rh_article: article HASHREF structure from getArticles
 Globals      : none

function isSecondaryArticle

 Title        : isSecondaryArticle
 Usage        : isSecondaryArticle($rh_article)
 Prerequisite : 
 Function     : Test if articleType is moby:Parameter (secondary article)
 Returns      : $response: BOOLEAN
 Args         : $rh_article: article HASHREF structure from getArticles
 Globals      : none

function _AnalyseSimple

 Title        : _AnalyseSimple
 Usage        : _AnalyseSimple($simple_bloc)
 Prerequisite : 
 Function     : Analyse a "Simple Bloc" from XSL transformation parsing
                Build a $rh_simple_article structure with fields:
                        'object_name'           => moby:articleName
                        'object_type'           => moby:Class
                        'object_namespace'      => moby:namespace
                        'object_id'             => moby:id
                        'object_content'        => text content of simple article
                        'object_xml'            => full xml content of article
                        'object_hasa'           => ARRAYREF of hasa elements 
                                                   (each one is structured in a same 
                                                   structured hash (recursivity)
                        'object_crossreference' => ARRAYREF of crossreferences objects 
                                                   (each one is structured in a hash with fields
                                                   'type', 'id', 'namespace')
 Returns      : $rh_simple: article HASHREF
 Args         : $simple_bloc: from parsing of a "simple" XSLT transformation
 Globals      : none

simpleResponse (stolen from MOBY::CommonSubs)

 name     : simpleResponse
 function : wraps a simple article in the appropriate (mobyData) structure
 usage    : $resp .= &simpleResponse($object, 'MyArticleName', $queryID);
 args     : (in order)
            $object   - (optional) a MOBY Object as raw XML
            $article  - (optional) an articeName for this article
            $query    - (optional, but strongly recommended) the queryID value for the
                        mobyData block to which you are responding
 notes    : as required by the API you must return a response for every input.
            If one of the inputs was invalid, you return a valid (empty) MOBY
            response by calling &simpleResponse(undef, undef, $queryID) with no arguments.

collectionResponse (stolen from MOBY::CommonSubs)

 name     : collectionResponse
 function : wraps a set of articles in the appropriate mobyData structure
 usage    : return responseHeader . &collectionResponse(\@objects, 'MyArticleName', $queryID) . responseFooter;
 args     : (in order)
            \@objects - (optional) a listref of MOBY Objects as raw XML
            $article  - (optional) an articeName for this article
            $queryID  - (optional, but strongly recommended) the mobyData ID
                        to which you are responding
 notes    : as required by the API you must return a response for every input.
            If one of the inputs was invalid, you return a valid (empty) MOBY
            response by calling &collectionResponse(undef, undef, $queryID).

complexResponse (stolen from MOBY::CommonSubs)

 name     : complexResponse
 function : wraps a set of articles in the one mobyData structure
 usage    : return responseHeader . &complexResponse(\@a_article_structures, $queryID) . responseFooter;
 args     : (in order)
            \@a_article_structures - (optional) a listref of structured articles 
                %h_article = (
                                article_type => 'collection/simple', 
                                article_content => 'MOBY XML formatted content', 
                                article_name => 'articleName attribut')
            $queryID  - (optional, but strongly recommended) the mobyData ID
                        to which you are responding
=cut

sub complexResponse { my ($ra_data, $qID) = @_;

    $ra_data ||= [];
    $qID  ||= '';
    unless ((ref($ra_data) =~ /array/i) && $ra_data->[0])
    {                                       # we're expecting an arrayref as input data,and it must not be empty
        return "<moby:mobyData moby:queryID='$qID'/>";
    }
    my $moby_data_content = '';
    foreach my $rh_data_block (@{$ra_data})
    {
        my $article_name = $rh_data_block->{article_name};
        my $article_content = $rh_data_block->{article_content};
        if ($rh_data_block->{article_type} =~ /collection/i)
        {
            my $collection_content = "<moby:Collection moby:articleName='$article_name'>\n";
            if ((ref($article_content) =~ /array/i) && $article_content->[0])
            {
                foreach my $simple_element (@{$article_content})
                {
                    $collection_content .= "\t<moby:Simple>\n\t$simple_element\n\t</moby:Simple>\n";
                }
            }
            else
            {
                $collection_content .= "\t<moby:Simple/>\n";
            }
            $collection_content .= "</moby:Collection>\n";
            $moby_data_content .= $collection_content;
        }
        else
        {
            my $simple_content = "<moby:Simple moby:articleName='$article_name'>\n\t$article_content\n</moby:Simple>";
            $moby_data_content .= $simple_content;
        }
    }
    return "<moby:mobyData moby:queryID='$qID'>\n\t$moby_data_content\n</moby:mobyData>\n";
}

responseHeader (stolen from MOBY::CommonSubs)

function: print the XML string of a MOBY response header +/- serviceNotes +/- Exceptions

usage:

  responseHeader('illuminae.com')
  responseHeader(
                -authority => 'illuminae.com',
                -note => 'here is some data from the service provider'
                -exception=>'an xml encoded exception string')

args: a string representing the service providers authority URI, OR a set of named arguments with the authority and the service provision notes which can include already xml encoded exceptions

caveat :

notes: returns everything required up to the response articles themselves. i.e. something like:

 <?xml version='1.0' encoding='UTF-8'?>
    <moby:MOBY xmlns:moby='http://www.biomoby.org/moby'>
       <moby:Response moby:authority='http://www.illuminae.com'>

encodeException (stolen from MOBY::CommonSubs)

function: wraps a Biomoby Exception with all its parameters into the appropiate MobyData structure

usage:

  encodeException(
                -refElement => 'refers to the queryID of the offending input mobyData',
                -refQueryID => 'refers to the articleName of the offending input Simple or Collection'
                -severity=>'error'
                -exceptionCode=>'An error code '
                -exceptionMessage=>'a human readable description for the error code')

args:the different arguments required by the mobyException API severity can be either error, warning or information valid error codes are decribed on the biomoby website

notes: returns everything required to use for the responseHeader:

  <moby:mobyException moby:refElement='input1' moby:refQueryID='1' moby:severity =''>
                <moby:exceptionCode>600</moby:exceptionCode>
                <moby:exceptionMessage>Unable to execute the service</moby:exceptionMessage>
            </moby:mobyException>

responseFooter (stolen from MOBY::CommonSubs)

 name     : responseFooter
 function : print the XML string of a MOBY response footer
 usage    : return responseHeader('illuminae.com') . $DATA . responseFooter;
 notes    :  returns everything required after the response articles themselves
             i.e. something like:
  </moby:Response>
     </moby:MOBY>

function _IsCollection

 Title        : _IsCollection
 Usage        : _IsCollection($article_type)
 Prerequisite : 
 Function     : Compares a string to string 'collection'
                Remove namespace 'moby:' from parameter string 
                Case insensitive
 Returns      : BOOLEAN
 Args         : $articletype: a string
 Globals      : none

function _IsSimple

 Title        : _IsSimple
 Usage        : _IsSimple($article_type)
 Prerequisite : 
 Function     : Compares a string to string 'simple'
                Remove namespace 'moby:' from parameter string 
                Case insensitive
 Returns      : BOOLEAN
 Args         : $articletype: a string
 Globals      : none

function _IsSecondary

 Title        : _IsSecondary
 Usage        : _IsSecondary($article_type)
 Prerequisite : 
 Function     : Compares a string to string 'parameter'
                Remove namespace 'moby:' from parameter string 
                Case insensitive
 Returns      : BOOLEAN
 Args         : $articletype: a string
 Globals      : none

_rearrange (stolen from MOBY::CommonSubs)

function _AnalyseServiceNotes

 Title        : _AnalyseServiceNotes
 Usage        : _AnalyseServiceNotes($simple_bloc)
 Prerequisite : 
 Function     : Analyse a "Simple Bloc" from XSL transformation parsing
                        Build a $rh_simple_article structure with fields:
                        'object_name'           => moby:articleName
                        'object_type'           => moby:Class
                        'object_namespace'      => moby:namespace
                        'object_id'             => moby:id
                        'object_content'        => text content of simple article
                        'object_xml'            => full xml content of article
                        'object_hasa'           => ARRAYREF of hasa elements 
                                                   (each one is structured in a same 
                                                   structured hash (recursivity)
                        'object_crossreference' => ARRAYREF of crossreferences objects 
                                                   (each one is structured in a hash with fields
                                                   'type', 'id', 'namespace')
 Returns      : $services_notes: article HASHREF
                                $ra_exceptions: article HASHREF
 Args         : $service_notes_bloc: from parsing of a "serviceNotes" XSLT transformation
 Globals      : none