SOAP-Lite

 view release on metacpan or  search on metacpan

lib/SOAP/Serializer.pod  view on Meta::CPAN

# ======================================================================
#
# Copyright (C) 2000-2004 Paul Kulchenko (paulclinger@yahoo.com)
# SOAP::Lite is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
#
# ======================================================================

=pod

=head1 NAME

SOAP::Serializer - the means by which the toolkit manages the expression of data as XML

=head1 DESCRIPTION

The SOAP::Serializer class is the means by which the toolkit manages the expression of data as XML. The object that a SOAP::Lite instance uses by default is generally enough for the task, with no need for the application to create its own. The main p...

=head1 METHODS

=over

=item new(optional key/value pairs)

    $serialize = SOAP::Serializer->new( );

This is the constructor method for the class. In addition to creating a basic object and initializing it with default values, the constructor can also take names and values for most of the accessor methods that the class supports.

=item envelope(method, data arguments)

    $serialize->envelope(fault => $fault_obj);

Provides the core purpose for the SOAP::Serializer class. It creates the full SOAP envelope based on the input passed in to it. The data arguments passed in the list of parameters to the method are divided into two sublists: any parameters that are L...

=item context

    $serialize->context->packager();

This provides access to the calling context of C<SOAP::Serializer>. In a client side context the often means a reference to an instance of SOAP::Lite. In a server side context this means a reference to a SOAP::Server instance.

=over

=item method

The envelope is being created to encapsulate a RPC-style method call.

=item response

The message being created is that of a response stemming from a RPC-style method call.

=item fault

For this specifier, the envelope being created is to transmit a fault.

=item freeform

This identifier is used as a general-case encoding style for messages that
don't fit into any of the previous cases. The arguments are encoded into the
envelope's Body tag without any sort of context sensitivity.

=back

Any value other than these four results in an error.

=item envprefix(optional value)

    $serialize->envprefix('env');

Gets or sets the prefix that labels the SOAP envelope namespace. This defaults to SOAP-ENV.

=item encprefix(optional value)

    $serialize->envprefix('enc');

Gets or sets the prefix that labels the SOAP encoding namespace. Defaults to SOAP-ENC.

=item soapversion(optional value)

    $serialize->soapversion('1.2');

If no parameter is given, returns the current version of SOAP that is being used as the basis for serializing messages. If a parameter is given, attempts to set that as the version of SOAP being used. The value should be either 1.1 or 1.2. When the S...

=item xmlschema(optional value)

    $serialize->xmlschema($xml_schema_1999);

Gets or sets the URN for the schema being used to express the structure of the XML generated by the serializer. If setting the value, the input must be the full URN for the new schema and is checked against the list of known SOAP schemas.

=item register_ns

The register_ns subroutine allows users to register a global namespace
with the SOAP Envelope. The first parameter is the namespace, the second
parameter to this subroutine is an optional prefix. If a prefix is not
provided, one will be generated automatically for you. All namespaces
registered with the serializer get declared in the <soap:Envelope />
element.

=item find_prefix

The find_prefix subroutine takes a namespace as a parameter and returns
the assigned prefix to that namespace. This eliminates the need to declare
and redeclare namespaces within an envelope. This subroutine is especially
helpful in determining the proper prefix when assigning a type to a
SOAP::Data element. A good example of how this might be used is as follows:

    SOAP::Data->name("foo" => $inputParams{'foo'})
       ->type($client->serializer->find_prefix('urn:Foo').':Foo');

=back

=head1 CUSTOM DATA TYPES

When serializing an object, or blessed hash reference, into XML, C<SOAP::Serializer> first checks to see if a subroutine has been defined for the corresponding class name. For example, in the code below, C<SOAP::Serializer> will check to see if a sub...

   $foo = MyModule::MyPackage->new;
   my $client = SOAP::Lite
      ->uri($NS)
      ->proxy($HOST);
   $som = $client->someMethod(SOAP::Data->name("foo" => $foo));

=head1 as_TypeName SUBROUTINE REQUIREMENTS

=over

=item Naming Convention

The subroutine should always be prepended with C<as_> followed by the type's name. The type's name must have all colons (':') substituted with an underscore ('_').

=item Input

The input to C<as_TypeName> will have at least one parameter, and at most four parameters. The first parameter will always be the value or the object to be encoded. The following three parameters depend upon the context of the value/object being enco...

If the value/object being encoded was part of a C<SOAP::Data> object (as in the above example), then the second, third and fourth parameter will be the C<SOAP::Data> element's name, type, and attribute set respectively. If on the other hand, the valu...

   $foo = MyModule::MyPackage->new;
   my $client = SOAP::Lite
      ->uri($NS)
      ->proxy($HOST);
   $som = $client->someMethod($foo);

Then the second and third parameters will be the class name of the value/object being encoded (e.g. "MyModule::MyPackage" in the example above), and the fourth parameter will be an empty hash.

=item Output

The encoding subroutine must return an array containing three elements: 1) the name of the XML element, 2) a hash containing the attributes to be placed into the element, and 3) the value of the element.

=back

=head1 AUTOTYPING

When the type of an element has not been declared explicitly, SOAP::Lite must "guess" at the object's type. That is due to the fact that the only form of introspection that Perl provides (through the use of the C<ref> subroutine) does not provide eno...

To work around this limitation, the C<SOAP::Serializer::typelookup> hash was created. This hash is populated with all the data types that the current C<SOAP::Serializer> can auto detect. Users and developers are free to modify the contents of this ha...

When C<SOAP::Serializer> is asked to encode an object into XML, it goes through the following steps. First, C<SOAP::Serializer> checks to see if a type has been explicitly stated for the current object. If a type has been provided C<SOAP::Serializer>...

To do so, C<SOAP::Serializer> runs in sequence a set of tests stored in the C<SOAP::Serializer::typelookup> hash. C<SOAP::Serializer> continues to run each test until one of the tests returns true, indicating that the type of the object has been dete...

The following table contains the set of data types detectable by C<SOAP::Lite> by default and the order in which their corresponding test subroutine will be run, according to their precedence value.

  Table 1 - Autotyping Precedence

  TYPENAME    PRECEDENCE VALUE
  ----------------------------
  base64      10
  int         20
  long        25
  float       30
  gMonth      35
  gDay        40
  gYear       45
  gMonthDay   50
  gYearMonth  55
  date        60
  time        70
  dateTime    75
  duration    80
  boolean     90
  anyURI      95
  string      100


=head2 REGISTERING A NEW DATA TYPE

To register a new data type that can be automatically detected by C<SOAP::Lite> and then serialized into XML, the developer must provide the following four things:

=over

=item *

The name of the new data type.

=item *

A subroutine that is capable of detecting whether a value passed to it is of the corresponding data type.

=item *

A number representing the test subroutine's precedence relative to all the other types' test subroutinestypes. See I<Table 1 - Autotyping Precedence>.

=item *

A subroutine that is capable of providing C<SOAP::Serializer> with the information necessary to serialize an object of the corresponding data type into XML.

=back

=head3 EXAMPLE 1

If, for example, you wish to create a new datatype called C<uriReference> for which you would like Perl values to be automatically detected and serialized into, then you follow these steps.

B<Step 1: Write a Test Subroutine>

The test subroutine will have passed to it by C<SOAP::Serializer> a value to be tested. The test subroutine must return 1 if the value passed to it is of the corresponding type, or else it must return 0.

    sub SOAP::Serializer::uriReferenceTest {
      my ($value) = @_;
      return 1 if ($value =~ m!^http://!);
      return 0;
    }

B<Step 2: Write an Encoding Subroutine>

The encoding subroutine provides C<SOAP::Serializer> with the data necessary to encode the value passed to it into XML. The encoding subroutine name's should be of the following format: C<as_><Type Name>.

The encoding subroutine will have passed to it by C<SOAP::Serializer> four parameters: the value to be encoded, the name of the element being encoded, the assumed type of the element being encoded, and a reference to a hash containing the attributes ...

  sub SOAP::Serializer::as_uriReference {
    my $self = shift;
    my($value, $name, $type, $attr) = @_;
    return [$name, {'xsi:type' => 'xsd:uriReference', %$attr}, $value];
  }

B<Step 3: Register the New Data Type>

To register the new data type, simply add the type to the C<SOAP::Serializer::typelookup> hash using the type name as the key, and an array containing the precedence value, the test subroutine, and the encoding subroutine.

  $s->typelookup->{uriReference}
      = [11, \&uriReferenceTest, 'as_uriReference'];

I<Tip: As a short hand, you could just as easily use an anonymous test subroutine when registering the new datatype in place of the C<urlReferenceTest> subroutine above. For example:>

  $s->typelookup->{uriReference}
      = [11, sub { $_[0] =~ m!^http://! }, 'as_uriReference'];

Once complete, C<SOAP::Serializer> will be able to serialize the following C<SOAP::Data> object into XML:

  $elem = SOAP::Data->name("someUri" => 'http://yahoo.com')->type('uriReference');

C<SOAP::Serializer> will also be able to automatically determine and serialize the following untyped C<SOAP::Data> object into XML:

  $elem = SOAP::Data->name("someUri" => 'http://yahoo.com');

=head1 ACKNOWLEDGEMENTS

Special thanks to O'Reilly publishing which has graciously allowed SOAP::Lite to republish and redistribute large excerpts from I<Programming Web Services with Perl>, mainly the SOAP::Lite reference found in Appendix B.

=head1 COPYRIGHT

Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHORS

Paul Kulchenko (paulclinger@yahoo.com)

Randy J. Ray (rjray@blackperl.com)

Byrne Reese (byrne@majordojo.com)

=cut

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 2.421 seconds using v1.00-cache-2.02-grep-82fe00e-cpan-9f2165ba459b )