File Coverage

blib/lib/W3C/SOAP/Document.pm
Criterion Covered Total %
statement 37 39 94.8
branch n/a
condition n/a
subroutine 13 13 100.0
pod n/a
total 50 52 96.1


line stmt bran cond sub pod time code
1             package W3C::SOAP::Document;
2              
3             # Created on: 2012-05-27 19:26:43
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 1     1   1809 use Moose;
  1         2  
  1         8  
10 1     1   6140 use warnings;
  1         2  
  1         23  
11 1     1   5 use version;
  1         1  
  1         7  
12 1     1   63 use Carp qw/carp croak cluck confess longmess/;
  1         1  
  1         61  
13 1     1   4 use Scalar::Util;
  1         2  
  1         34  
14 1     1   5 use List::Util;
  1         2  
  1         41  
15 1     1   4 use Data::Dumper qw/Dumper/;
  1         1  
  1         43  
16 1     1   4 use English qw/ -no_match_vars /;
  1         2  
  1         7  
17 1     1   349 use Try::Tiny;
  1         1  
  1         46  
18 1     1   5 use URI;
  1         1  
  1         26  
19 1     1   413 use W3C::SOAP::Utils qw/normalise_ns ns2module/;
  1         2  
  1         6  
20 1     1   1004 use W3C::SOAP::Exception;
  1         2  
  1         49  
21 1     1   321 use XML::LibXML;
  0            
  0            
22              
23             our $VERSION = version->new('0.11');
24              
25             has string => (
26             is => 'rw',
27             isa => 'Str',
28             );
29             has location => (
30             is => 'rw',
31             isa => 'Str',
32             );
33             has xml => (
34             is => 'ro',
35             isa => 'XML::LibXML::Document',
36             required => 1,
37             );
38             has xpc => (
39             is => 'ro',
40             isa => 'XML::LibXML::XPathContext',
41             builder => '_xpc',
42             clearer => 'clear_xpc',
43             predicate => 'has_xpc',
44             lazy => 1,
45             );
46             has target_namespace => (
47             is => 'rw',
48             isa => 'Str',
49             builder => '_target_namespace',
50             predicate => 'has_target_namespace',
51             lazy => 1,
52             );
53             has ns_module_map => (
54             is => 'rw',
55             isa => 'HashRef[Str]',
56             required => 1,
57             predicate => 'has_ns_module_map',
58             default => sub{{}},
59             );
60             has module => (
61             is => 'rw',
62             isa => 'Str',
63             predicate => 'has_module',
64             builder => '_module',
65             lazy => 1,
66             );
67             has module_base => (
68             is => 'rw',
69             isa => 'Str',
70             predicate => 'has_module_base',
71             );
72              
73             around BUILDARGS => sub {
74             my ($orig, $class, @args) = @_;
75             my $args
76             = !@args ? {}
77             : @args == 1 ? $args[0]
78             : {@args};
79              
80             delete $args->{module_base} if ! defined $args->{module_base};
81              
82             if ( $args->{string} ) {
83             try {
84             $args->{xml} = XML::LibXML->load_xml(string => $args->{string});
85             }
86             catch {
87             chomp $_;
88             W3C::SOAP::Exception::XML->throw( error => $_, faultstring => $_ );
89             };
90             }
91             elsif ( $args->{location} ) {
92             try {
93             $args->{xml} = XML::LibXML->load_xml(location => $args->{location});
94             }
95             catch {
96             chomp $_;
97             W3C::SOAP::Exception::XML->throw( error => $_, faultstring => $args->{location} );
98             };
99             }
100              
101             return $class->$orig($args);
102             };
103              
104             sub _xpc {
105             my ($self) = @_;
106             my $xpc = XML::LibXML::XPathContext->new($self->xml);
107             $xpc->registerNs(xs => 'http://www.w3.org/2001/XMLSchema');
108             $xpc->registerNs(xsd => 'http://www.w3.org/2001/XMLSchema');
109             $xpc->registerNs(wsdl => 'http://schemas.xmlsoap.org/wsdl/');
110             $xpc->registerNs(wsp => 'http://schemas.xmlsoap.org/ws/2004/09/policy');
111             $xpc->registerNs(wssp => 'http://www.bea.com/wls90/security/policy');
112             $xpc->registerNs(soap => 'http://schemas.xmlsoap.org/wsdl/soap/');
113              
114             return $xpc;
115             }
116              
117             my $anon = 0;
118             sub _target_namespace {
119             my ($self) = @_;
120             my $ns = $self->xml->getDocumentElement->getAttribute('targetNamespace');
121             my $xpc = $self->xpc;
122             $xpc->registerNs(ns => $ns) if $ns;
123              
124             $ns ||= $self->location || 'NsAnon' . $anon++;
125              
126             return $ns;
127             }
128              
129             sub _module {
130             my ($self) = @_;
131             return $self->get_module_name( $self->target_namespace );
132             }
133              
134             sub get_module_name {
135             my ($self, $ns) = @_;
136             confess "No namespace given!" if !defined $ns;
137              
138             # namespace may be empty but map must be a module
139             if ( ! $self->ns_module_map->{normalise_ns($ns)} ) {
140              
141             # construct module name if we have a base name
142             if ( $self->has_module_base ) {
143             $self->ns_module_map->{normalise_ns($ns)}
144             = $self->module_base . '::' . ns2module($ns);
145             }
146              
147             # copy the unnormalised module name if we have one
148             if ( ! $self->ns_module_map->{normalise_ns($ns)} && $self->ns_module_map->{$ns} ) {
149             $self->ns_module_map->{normalise_ns($ns)} = $self->ns_module_map->{$ns};
150             }
151              
152             # all else fails throw an error
153             if ( ! $self->ns_module_map->{normalise_ns($ns)} ) {
154             confess "No mapping specified for the namespace $ns!\n"
155             . "If you are using xsd-parser or wsdl-parser try adding to your command\n"
156             . " -n '$ns=My::NameSpace'\n";
157             }
158             }
159              
160             return $self->ns_module_map->{normalise_ns($ns)};
161             }
162              
163             1;
164              
165             __END__
166              
167             =head1 NAME
168              
169             W3C::SOAP::Document - Object to represent an XML Document
170              
171             =head1 VERSION
172              
173             This documentation refers to W3C::SOAP::Document version 0.11.
174              
175             =head1 SYNOPSIS
176              
177             use W3C::SOAP::Document;
178              
179             # Instanciate a new document from a string
180             my $xml = W3C::SOAP::Document( string => $string );
181              
182             # From a url or file
183             my $xml = W3C::SOAP::Document->new( location => 'http://eg.com/schema.xsd' );
184              
185             =head1 DESCRIPTION
186              
187             C<W3C::SOAP::Document> takes an XML document from a string/file/url/L<XML::LibXML>
188             object and parses it to extract the important information about the document. This
189             the base class for L<W3C::SOAP::XSD::Document> and L<W3C::SOAP::WSDL::Document>.
190              
191             =head1 SUBROUTINES/METHODS
192              
193             =over 4
194              
195             =item C<new ( location => ... || string => ... || xml => ... )>
196              
197             Creates a new C<W3C::SOAP::Document> object.
198              
199             =item C<get_module_name ( $namespace )>
200              
201             Get the Perl module name for a XML namespace.
202              
203             =back
204              
205             =head1 DIAGNOSTICS
206              
207             =head1 CONFIGURATION AND ENVIRONMENT
208              
209             =head1 DEPENDENCIES
210              
211             =head1 INCOMPATIBILITIES
212              
213             =head1 BUGS AND LIMITATIONS
214              
215             There are no known bugs in this module.
216              
217             Please report problems to Ivan Wills (ivan.wills@gmail.com).
218              
219             Patches are welcome.
220              
221             =head1 AUTHOR
222              
223             Ivan Wills - (ivan.wills@gmail.com)
224              
225             =head1 LICENSE AND COPYRIGHT
226              
227             Copyright (c) 2012 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
228             All rights reserved.
229              
230             This module is free software; you can redistribute it and/or modify it under
231             the same terms as Perl itself. See L<perlartistic>. This program is
232             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
233             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
234             PARTICULAR PURPOSE.
235              
236             =cut