[%# A template for a service implementation code
      (an empty implementation of a service)
    ============================================

    Expected/recognized parameters:

      base         ... a service base definition
                       (type SADI:::Service::Instance)
	  module_name  ... a scalar string representing the module name
      impl         ... a service implementation details
                       (type HASH)
      static_impl  ... if true, the static option will be enabled
      ref          ... a CODE returning ref() of the given argument
-%]
#-----------------------------------------------------------------
# Service name: [% base.ServiceName %]
# Authority:    [% base.Authority %]
# Created:      [% USE Date (format = '%d-%b-%Y %H:%M:%S %Z') %][% Date.format %]
# Contact:      [% base.Provider %]
# Description:  [% USE description = String (base.Description) %]
#               [%- description.replace("\n", "\n#\t") %]
#-----------------------------------------------------------------

package [% impl.package %];

use FindBin qw( $Bin );
use lib $Bin;

#-----------------------------------------------------------------
# This is a mandatory section - but you can still choose one of
# the two options (keep one and commented out the other):
#-----------------------------------------------------------------
use SADI::Base;
[%- IF static_impl == 1 %][% opt1 = '#'; opt2 = '' %][% ELSE %][% opt1 = ''; opt2 = '#' %][% END %]
# --- (1) this option loads dynamically everything
[% opt1 %]BEGIN {
[% opt1 %]    use SADI::Generators::GenServices;
[% opt1 %]    new SADI::Generators::GenServices->load(
[% opt1 %]	 service_names => ['[% base.ServiceName %]']);
[% opt1 %]}

# --- (2) this option uses pre-generated module
#  You can generate the module by calling a script:
#    sadi-generate-services -b [% base.Authority %] [% base.ServiceName %]
#  then comment out the whole option above, and uncomment
#  the following line (and make sure that Perl can find it):
[% opt2 %]use [% module_name %];

# (this to stay here with any of the options above)
use vars qw( @ISA );
@ISA = qw( [% module_name %] );
use strict;

# add vocabulary use statements
use SADI::RDF::Predicates::DC_PROTEGE;
use SADI::RDF::Predicates::FETA;
use SADI::RDF::Predicates::OMG_LSID;
use SADI::RDF::Predicates::OWL;
use SADI::RDF::Predicates::RDF;
use SADI::RDF::Predicates::RDFS;

#-----------------------------------------------------------------
# process_it
#    This method is called for every client request.
#    Input data in the array reference, $values, are of type 
#      RDF::Core::Resource.
#
#      RDF::Core::Resource contains the following methods:
#         * new($URI)
#         * getURI - gets the URI for your Resource
#         * getNamespace - gets the namespace of the Resource
#         * getLocalValue - gets the value of the Resource
#         * equals($other) - checks equality of 2 Resources
#
#    $core is a reference to a SADI::RDF::Core object.
#
#    SADI::RDF::Core contains the following methods: 
#         * Signature() - gets the SADI::Service::Instance 
#               object backing this SADI::RDF::Core reference
#         * getInputNodes() - returns the RDF::Core::Resource 
#               nodes representing the input based on the 
#               input class for this service
#         * getStatements -
#            get an array of RDF::Core::Statements given a subject, object, and/or predicate from the input data
#            
#              %args
#                  subject   => the URI of the subject for which you want to retrieve statements for
#                  object    => the URI of the object for which you want to retrieve statements for
#                  predicate => the URI of the predicate for which you want to retrieve statements for
#             
#              B<subject, object and predicate are all optional.>
#              
#              returns
#                  a reference to an array of RDF::Core::Statements that match the given subject, object and predicate
#         * getObjects
#                get an array of RDF::Core::Resource nodes given a subject and predicate from the input data
#                
#                  %args
#                      subject   => the URI of the subject for which you want to retrieve objects for
#                      predicate => the URI of the predicate for which you want to retrieve objects for
#                  
#                  B<subject, object and predicate are all optional.>
#                  
#                  returns
#                      a reference to an array of RDF::Core::Resource that match the given subject and predicate
#         * addOutputData
#                add an output triple to the model; the predicate of the triple
#                  is automatically extracted from the ServicePredicate.
#                  
#                  You can pass a URI or an RDF::Core::Resource as the "value" argument.  
#                  The node is automatically rdf:typed as the OutputClass if you include
#                  the "typed_as_output" argument as true.
#                  
#                  If you pass a "value" that looks like a URI, then this routine WILL ASSUME
#                  THAT YOU WANT IT TO BE AN OBJECT, NOT A SCALAR VALUE.  To over-ride this,
#                  set the boolean "force_literal" argument.  If you pass an RDF::Core::Resource
#                  together with the force_literal argument, the URI of the RDF::Core::Resource
#                  will be extracted and added as a literal value rather than as an object.
#                
#                  args
#                     node => $URI  (the URI string or RDF::Core::Resource of the subject node
#                             or a subclass of SADI::Data::OWL::Class )
#                       NOTE:
#                          if $URI->isa(SADI::Data::OWL::Class) created via
#                          sadi-generate-datatypes script then all RDF statements
#                          for this resource are added to our model and all 
#                          other arguments are ignored!
#                     value => $val  (a string value)
#                     predicate => $URI (optional - the predicate to put between them.  
#                                        Defaults to $self->ServicePredicate)
#                     typed_as_output => boolean (if present output is rdf:typed as output class)
#                     force_literal => boolean
#                     label => $label (string); label for value node, only if value is a URI
#
# Make sure to read the perldoc for up to date information on any module mentioned here!
#-----------------------------------------------------------------
sub process_it {
    my ($self, $values, $core) = @_;
    # empty data, then return
    return unless $values;

    my @inputs = @$values;
    # iterate over each input
    foreach my $input (@inputs) {
    	# NOTE: this fills in the log file
    	$LOG->info ("Input data (" 
    		. $input->getURI ? $input->getURI : "no_uri" 
    		. ")"
    		. $input->getLocalValue ? ":\n" . $input->getLocalValue : ""
    		."")
      		if defined $input;
    	# do something with $input ... (sorry, can't help with that)
	
        # fill in the output nodes - this is what you need to do!
        foreach my $output (0..2) {
        # for example ...
         	$core->addOutputData(
        		node => $input->getURI,
                value => "$output",
        	    predicate => "http://sadiframework.org/ontologies/predicates.owl#somePredicate$output"
        	);
        }
    }
}

1;
__END__

=head1 NAME

[% impl.package %] - a SADI service

=head1 SYNOPSIS

=head1 DESCRIPTION

[% base.Description %]

=head1 CONTACT

B<Authority>: [% base.Authority %]

B<Email>: [% base.Provider %]

=cut
