Loading ...
Sorry, an error occurred while loading the content.
 

RE: [soaplite] Receiving a dateTime timestamp

Expand Messages
  • Igor Korolev
    For now, I subclassed SOAP::Lite adding _fault key to the object returned by SOAP::Lite::service method. I also added fault() method which returns
    Message 1 of 6 , Jul 14, 2003
      For now, I subclassed SOAP::Lite adding '_fault' key to the object
      returned by SOAP::Lite::service method. I also added fault() method
      which returns $svc->{_fault}. This hack resolves my problem.

      #!/usr/bin/perl
      my ($svc, $resp);
      my $wsurl = 'http://www20.digitalriver.com/rcsdev/macro.wsdl';
      use SOAP::Lite::DR +trace => 'debug';

      eval
      {
      $svc = SOAP::Lite::DR->service($wsurl);
      $resp = $svc->placeOrder('junk', 'parameters');
      };
      die "Got Error: $@" if($@);
      unless( $resp )
      {
      my $result = $svc->fault;
      print "STRING: $result->{faultstring}\nCODE: $result->{faultcode}\n";
      }

      # ======================================================================
      #
      package SOAP::Lite::DR;

      use strict;

      use SOAP::Lite;

      use vars qw(@ISA);
      @ISA = ('SOAP::Lite');

      sub service {
      my $field = '_service';
      my $self = shift->new;
      return $self->{$field} unless @_;

      my %services = %{SOAP::Schema::DR->schema($self->{$field} = shift)->parse(@_)->load->services};

      Carp::croak "More than one service in service description. Service and port names have to be specified\n"
      if keys %services > 1;
      return (keys %services)[0]->new;
      }

      sub call { SOAP::Trace::trace('()');
      my $self = shift;

      return $self->{_call} unless @_;

      my $serializer = $self->serializer;

      die "Transport is not specified (using proxy() method or service description)\n"
      unless defined $self->proxy && UNIVERSAL::isa($self->proxy => 'SOAP::Client');

      $serializer->on_nonserialized($self->on_nonserialized);
      my $response = $self->transport->send_receive(
      endpoint => $self->endpoint,
      action => scalar($self->on_action->($serializer->uriformethod($_[0]))),
      # leave only parameters so we can later update them if required
      envelope => $serializer->envelope(method => shift, @_),
      encoding => $serializer->encoding,
      );

      return $response if $self->outputxml;

      # deserialize and store result
      my $result = $self->{_call} = eval { $self->deserializer->deserialize($response) } if $response;

      if (!$self->transport->is_success || # transport fault
      $@ || # not deserializible
      # fault message even if transport OK
      # or no transport error (for example, fo TCP, POP3, IO implementations)
      UNIVERSAL::isa($result => 'SOAP::SOM') && $result->fault) {
      #############################################
      $self->{_fault} = $result->fault if $result;
      #############################################
      return $self->{_call} = ($self->on_fault->($self, $@ ? $@ . ($response || '') : $result) || $result);
      }

      return unless $response; # nothing to do for one-ways

      # little bit tricky part that binds in/out parameters
      if (UNIVERSAL::isa($result => 'SOAP::SOM') &&
      ($result->paramsout || $result->headers) &&
      $serializer->signature) {
      my $num = 0;
      my %signatures = map {$_ => $num++} @{$serializer->signature};
      for ($result->dataof(SOAP::SOM::paramsout), $result->dataof(SOAP::SOM::headers)) {
      my $signature = join $;, $_->name, $_->type || '';
      if (exists $signatures{$signature}) {
      my $param = $signatures{$signature};
      my($value) = $_->value; # take first value
      UNIVERSAL::isa($_[$param] => 'SOAP::Data') ? $_[$param]->SOAP::Data::value($value) :
      UNIVERSAL::isa($_[$param] => 'ARRAY') ? (@{$_[$param]} = @$value) :
      UNIVERSAL::isa($_[$param] => 'HASH') ? (%{$_[$param]} = %$value) :
      UNIVERSAL::isa($_[$param] => 'SCALAR') ? (${$_[$param]} = $$value) :
      ($_[$param] = $value)
      }
      }
      }
      return $result;
      }

      # ======================================================================

      package SOAP::Schema::DR;

      use Carp ();


      use vars qw(@ISA);
      @ISA = ('SOAP::Schema');

      sub stub {
      my $self = shift->new;
      my $package = shift;
      my $services = $self->services->{$package};
      my $schema = $self->schema;
      join("\n",
      "package $package;\n",
      "# -- generated by SOAP::Lite::DR",
      ($schema ? "# -- generated from $schema [@{[scalar localtime]}]\n" : "\n"),
      'my %methods = (',
      (map { my $service = $_;
      join("\n",
      " $_ => {",
      map(" $_ => '$services->{$service}{$_}',", qw/endpoint soapaction uri/),
      " parameters => [",
      map(" SOAP::Data->new(name => '" . $_->name .
      "', type => '" . $_->type .
      "', attr => {" . do{ my %attr = %{$_->attr}; join ', ', map {"'$_' => '$attr{$_}'"} grep {/^xmlns:(?!-)/} keys %attr} .
      "}),", @{$services->{$service}{parameters}}),
      " ],\n },",
      ),
      } keys %$services),
      ");", <<'EOP');

      use SOAP::Lite::DR;
      use Exporter;
      use Carp ();

      use vars qw(@ISA $AUTOLOAD @EXPORT_OK %EXPORT_TAGS);
      @ISA = qw(Exporter SOAP::Lite::DR);
      @EXPORT_OK = (keys(%methods), 'fault');
      %EXPORT_TAGS = ('all' => [@EXPORT_OK]);

      no strict 'refs';
      for my $method (@EXPORT_OK) {
      my %method = %{$methods{$method}};
      *$method = sub {
      my $self = UNIVERSAL::isa($_[0] => __PACKAGE__)
      ? ref $_[0] ? shift # OBJECT
      # CLASS, either get self or create new and assign to self
      : (shift->self || __PACKAGE__->self(__PACKAGE__->new))
      # function call, either get self or create new and assign to self
      : (__PACKAGE__->self || __PACKAGE__->self(__PACKAGE__->new));

      ###############################################
      return $self->{_fault} if($method eq 'fault');
      ###############################################
      $self->proxy($method{endpoint} || Carp::croak "No server address (proxy) specified") unless $self->proxy;
      my @templates = @{$method{parameters}};
      my $som = $self
      -> endpoint($method{endpoint})
      -> uri($method{uri})
      -> on_action(sub{qq!"$method{soapaction}"!})
      -> call($method => map {@templates ? shift(@templates)->value($_) : $_} @_);
      UNIVERSAL::isa($som => 'SOAP::SOM') ? wantarray ? $som->paramsall : $som->result
      : $som;
      }
      }

      sub AUTOLOAD {
      my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
      return if $method eq 'DESTROY';

      die "Unrecognized method '$method'. List of available method(s): @EXPORT_OK\n";
      }

      1;
      EOP
      }

      1;


      -----Original Message-----
      From: Byrne Reese [mailto:breese@...]
      Sent: Monday, July 14, 2003 11:19 AM
      To: Erik van Zijst
      Cc: SOAP Lite Mailing List
      Subject: Re: [soaplite] Receiving a dateTime timestamp


      This is the trouble with Perl [5.x that is :)] - because it is loosely
      typed, it is difficult to discern what kind of object you want to
      serialize a xsd:dateTime object into. I suggest using a RegEx to grep
      out the parts you need and build a datetime object of your choosing.
      Then submit the code back to the group and perhaps it may find its way
      into the code base.

      Maybe SOAP::Lite could return an array reference similar to what is
      returned when I run:

      my (@time) = localtime();


      On Mon, 2003-07-14 at 07:07, Erik van Zijst wrote:
      > Hi folks,
      >
      > Please excuse my ignorance, but I'm a Java developer but I use
      > soaplite to do most of the testing of my new web services. It's more
      > convenient than writing a full-featured Java client.
      >
      > Anyway, I've got trouble receiving dateTime objects. When a service
      > returns:
      >
      > <newsDate xsi:type='xsd:dateTime'>2003-07-14T14:02:30.000Z</newsDate>
      >
      > and I print the timestamp using "print $result->result->{newsDate}", I
      > simply get the string "2003-07-14T14:02:30.000Z". How do I convert
      > this back into some kind of date object that I can print and process?
      >
      > cheers,
      > Erik
      >
      >
      >
      > Yahoo! Groups Sponsor
      > ADVERTISEMENT
      > click here
      >
      > To unsubscribe from this group, send an email to:
      > soaplite-unsubscribe@yahoogroups.com
      >
      >
      >
      > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
      --
      Byrne Reese
      Developer Program Manager
      Grand Central Communications



      To unsubscribe from this group, send an email to:
      soaplite-unsubscribe@yahoogroups.com



      Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
    • Igor Korolev
      Sorry, replied to the wrong email. Please ignore. ... From: Igor Korolev Sent: Monday, July 14, 2003 12:21 PM To: Byrne Reese; Erik van Zijst Cc: SOAP Lite
      Message 2 of 6 , Jul 14, 2003
        Sorry, replied to the wrong email. Please ignore.

        -----Original Message-----
        From: Igor Korolev
        Sent: Monday, July 14, 2003 12:21 PM
        To: Byrne Reese; Erik van Zijst
        Cc: SOAP Lite Mailing List
        Subject: RE: [soaplite] Receiving a dateTime timestamp


        For now, I subclassed SOAP::Lite adding '_fault' key to the object
        returned by SOAP::Lite::service method. I also added fault() method
        which returns $svc->{_fault}. This hack resolves my problem.

        #!/usr/bin/perl
        my ($svc, $resp);
        my $wsurl = 'http://www20.digitalriver.com/rcsdev/macro.wsdl';
        use SOAP::Lite::DR +trace => 'debug';

        eval
        {
        $svc = SOAP::Lite::DR->service($wsurl);
        $resp = $svc->placeOrder('junk', 'parameters');
        };
        die "Got Error: $@" if($@);
        unless( $resp )
        {
        my $result = $svc->fault;
        print "STRING: $result->{faultstring}\nCODE: $result->{faultcode}\n";
        }

        # ======================================================================
        #
        package SOAP::Lite::DR;

        use strict;

        use SOAP::Lite;

        use vars qw(@ISA);
        @ISA = ('SOAP::Lite');

        sub service {
        my $field = '_service';
        my $self = shift->new;
        return $self->{$field} unless @_;

        my %services = %{SOAP::Schema::DR->schema($self->{$field} = shift)->parse(@_)->load->services};

        Carp::croak "More than one service in service description. Service and port names have to be specified\n"
        if keys %services > 1;
        return (keys %services)[0]->new;
        }

        sub call { SOAP::Trace::trace('()');
        my $self = shift;

        return $self->{_call} unless @_;

        my $serializer = $self->serializer;

        die "Transport is not specified (using proxy() method or service description)\n"
        unless defined $self->proxy && UNIVERSAL::isa($self->proxy => 'SOAP::Client');

        $serializer->on_nonserialized($self->on_nonserialized);
        my $response = $self->transport->send_receive(
        endpoint => $self->endpoint,
        action => scalar($self->on_action->($serializer->uriformethod($_[0]))),
        # leave only parameters so we can later update them if required
        envelope => $serializer->envelope(method => shift, @_),
        encoding => $serializer->encoding,
        );

        return $response if $self->outputxml;

        # deserialize and store result
        my $result = $self->{_call} = eval { $self->deserializer->deserialize($response) } if $response;

        if (!$self->transport->is_success || # transport fault
        $@ || # not deserializible
        # fault message even if transport OK
        # or no transport error (for example, fo TCP, POP3, IO implementations)
        UNIVERSAL::isa($result => 'SOAP::SOM') && $result->fault) {
        #############################################
        $self->{_fault} = $result->fault if $result;
        #############################################
        return $self->{_call} = ($self->on_fault->($self, $@ ? $@ . ($response || '') : $result) || $result);
        }

        return unless $response; # nothing to do for one-ways

        # little bit tricky part that binds in/out parameters
        if (UNIVERSAL::isa($result => 'SOAP::SOM') &&
        ($result->paramsout || $result->headers) &&
        $serializer->signature) {
        my $num = 0;
        my %signatures = map {$_ => $num++} @{$serializer->signature};
        for ($result->dataof(SOAP::SOM::paramsout), $result->dataof(SOAP::SOM::headers)) {
        my $signature = join $;, $_->name, $_->type || '';
        if (exists $signatures{$signature}) {
        my $param = $signatures{$signature};
        my($value) = $_->value; # take first value
        UNIVERSAL::isa($_[$param] => 'SOAP::Data') ? $_[$param]->SOAP::Data::value($value) :
        UNIVERSAL::isa($_[$param] => 'ARRAY') ? (@{$_[$param]} = @$value) :
        UNIVERSAL::isa($_[$param] => 'HASH') ? (%{$_[$param]} = %$value) :
        UNIVERSAL::isa($_[$param] => 'SCALAR') ? (${$_[$param]} = $$value) :
        ($_[$param] = $value)
        }
        }
        }
        return $result;
        }

        # ======================================================================

        package SOAP::Schema::DR;

        use Carp ();


        use vars qw(@ISA);
        @ISA = ('SOAP::Schema');

        sub stub {
        my $self = shift->new;
        my $package = shift;
        my $services = $self->services->{$package};
        my $schema = $self->schema;
        join("\n",
        "package $package;\n",
        "# -- generated by SOAP::Lite::DR",
        ($schema ? "# -- generated from $schema [@{[scalar localtime]}]\n" : "\n"),
        'my %methods = (',
        (map { my $service = $_;
        join("\n",
        " $_ => {",
        map(" $_ => '$services->{$service}{$_}',", qw/endpoint soapaction uri/),
        " parameters => [",
        map(" SOAP::Data->new(name => '" . $_->name .
        "', type => '" . $_->type .
        "', attr => {" . do{ my %attr = %{$_->attr}; join ', ', map {"'$_' => '$attr{$_}'"} grep {/^xmlns:(?!-)/} keys %attr} .
        "}),", @{$services->{$service}{parameters}}),
        " ],\n },",
        ),
        } keys %$services),
        ");", <<'EOP');

        use SOAP::Lite::DR;
        use Exporter;
        use Carp ();

        use vars qw(@ISA $AUTOLOAD @EXPORT_OK %EXPORT_TAGS);
        @ISA = qw(Exporter SOAP::Lite::DR);
        @EXPORT_OK = (keys(%methods), 'fault');
        %EXPORT_TAGS = ('all' => [@EXPORT_OK]);

        no strict 'refs';
        for my $method (@EXPORT_OK) {
        my %method = %{$methods{$method}};
        *$method = sub {
        my $self = UNIVERSAL::isa($_[0] => __PACKAGE__)
        ? ref $_[0] ? shift # OBJECT
        # CLASS, either get self or create new and assign to self
        : (shift->self || __PACKAGE__->self(__PACKAGE__->new))
        # function call, either get self or create new and assign to self
        : (__PACKAGE__->self || __PACKAGE__->self(__PACKAGE__->new));

        ###############################################
        return $self->{_fault} if($method eq 'fault');
        ###############################################
        $self->proxy($method{endpoint} || Carp::croak "No server address (proxy) specified") unless $self->proxy;
        my @templates = @{$method{parameters}};
        my $som = $self
        -> endpoint($method{endpoint})
        -> uri($method{uri})
        -> on_action(sub{qq!"$method{soapaction}"!})
        -> call($method => map {@templates ? shift(@templates)->value($_) : $_} @_);
        UNIVERSAL::isa($som => 'SOAP::SOM') ? wantarray ? $som->paramsall : $som->result
        : $som;
        }
        }

        sub AUTOLOAD {
        my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
        return if $method eq 'DESTROY';

        die "Unrecognized method '$method'. List of available method(s): @EXPORT_OK\n";
        }

        1;
        EOP
        }

        1;


        -----Original Message-----
        From: Byrne Reese [mailto:breese@...]
        Sent: Monday, July 14, 2003 11:19 AM
        To: Erik van Zijst
        Cc: SOAP Lite Mailing List
        Subject: Re: [soaplite] Receiving a dateTime timestamp


        This is the trouble with Perl [5.x that is :)] - because it is loosely
        typed, it is difficult to discern what kind of object you want to
        serialize a xsd:dateTime object into. I suggest using a RegEx to grep
        out the parts you need and build a datetime object of your choosing.
        Then submit the code back to the group and perhaps it may find its way
        into the code base.

        Maybe SOAP::Lite could return an array reference similar to what is
        returned when I run:

        my (@time) = localtime();


        On Mon, 2003-07-14 at 07:07, Erik van Zijst wrote:
        > Hi folks,
        >
        > Please excuse my ignorance, but I'm a Java developer but I use
        > soaplite to do most of the testing of my new web services. It's more
        > convenient than writing a full-featured Java client.
        >
        > Anyway, I've got trouble receiving dateTime objects. When a service
        > returns:
        >
        > <newsDate xsi:type='xsd:dateTime'>2003-07-14T14:02:30.000Z</newsDate>
        >
        > and I print the timestamp using "print $result->result->{newsDate}", I
        > simply get the string "2003-07-14T14:02:30.000Z". How do I convert
        > this back into some kind of date object that I can print and process?
        >
        > cheers,
        > Erik
        >
        >
        >
        > Yahoo! Groups Sponsor
        > ADVERTISEMENT
        > click here
        >
        > To unsubscribe from this group, send an email to:
        > soaplite-unsubscribe@yahoogroups.com
        >
        >
        >
        > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
        --
        Byrne Reese
        Developer Program Manager
        Grand Central Communications



        To unsubscribe from this group, send an email to:
        soaplite-unsubscribe@yahoogroups.com



        Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/




        To unsubscribe from this group, send an email to:
        soaplite-unsubscribe@yahoogroups.com



        Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
      • Erik van Zijst
        Thanks Byrne. To be honest however this was not quite the answer I was hoping for :-)
        Message 3 of 6 , Jul 15, 2003
          Thanks Byrne. To be honest however this was not quite the answer I was
          hoping for :-)

          --- In soaplite@yahoogroups.com, Byrne Reese <breese@g...> wrote:
          > This is the trouble with Perl [5.x that is :)] - because it is loosely
          > typed, it is difficult to discern what kind of object you want to
          > serialize a xsd:dateTime object into. I suggest using a RegEx to grep
          > out the parts you need and build a datetime object of your choosing.
          > Then submit the code back to the group and perhaps it may find its way
          > into the code base.
          >
          > Maybe SOAP::Lite could return an array reference similar to what is
          > returned when I run:
          >
          > my (@time) = localtime();
          >
          >
          > On Mon, 2003-07-14 at 07:07, Erik van Zijst wrote:
          > > Hi folks,
          > >
          > > Please excuse my ignorance, but I'm a Java developer but I use
          > > soaplite to do most of the testing of my new web services. It's more
          > > convenient than writing a full-featured Java client.
          > >
          > > Anyway, I've got trouble receiving dateTime objects. When a service
          > > returns:
          > >
          > > <newsDate xsi:type='xsd:dateTime'>2003-07-14T14:02:30.000Z</newsDate>
          > >
          > > and I print the timestamp using "print $result->result->{newsDate}", I
          > > simply get the string "2003-07-14T14:02:30.000Z". How do I convert
          > > this back into some kind of date object that I can print and process?
          > >
          > > cheers,
          > > Erik
          > >
          > >
          > >
          > > Yahoo! Groups Sponsor
          > > ADVERTISEMENT
          > > click here
          > >
          > > To unsubscribe from this group, send an email to:
          > > soaplite-unsubscribe@yahoogroups.com
          > >
          > >
          > >
          > > Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
          > --
          > Byrne Reese
          > Developer Program Manager
          > Grand Central Communications
        Your message has been successfully submitted and would be delivered to recipients shortly.