File Coverage

blib/lib/ebXML/Message.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             package ebXML::Message;
2              
3             =head1 NAME
4              
5             ebXML::Message - encapsulate an ebMS message
6              
7             =head1 SYNOPSIS
8              
9             use ebXML::Message;
10              
11             # create new message
12              
13             my $message = ebXML::Message->new
14             (
15             'CPAId' => 'http://www.you.org/cpa/123456',
16             'Action' => 'NewPurchaseOrder',
17             'MessageId' => 12,
18             'RefMessageToId' => 11,
19             'Service' => ebXML::Message::Service->new
20             (
21             VALUE => 'QuoteToCollect',
22             Type => 'myservicetypes',
23             ),
24             );
25              
26             # write SOAP XML using DOM
27              
28             use XML::Xerses;
29              
30             # DOM Document
31             my $target = XML::Xerces::StdOutFormatTarget->new();
32             $writer->writeNode($target,$message->getOutput('DOM-Doc');
33              
34             # DOM generated / munged XML
35             print OUT $message->getOutput('DOM-XML');
36              
37              
38             # use message with SOAP::Lite to call webservice
39              
40             use SOAP::Lite;
41              
42             # SOAP::Data::Builder object
43             my $result = SOAP::Lite->uri('http://uri.to/WebService')
44             ->proxy('http://uri.to/soap.cgi')
45             ->parts($message->getMIMEParts)
46             ->call($message->getOutput('SOAP-Data'))
47             ->result;
48              
49             # SOAP::Data::Builder generated / munged XML
50             print OUT $message->getOutput('SOAP-XML');
51              
52              
53              
54             =head1 DESCRIPTION
55              
56             An ebXML message encapsulates all the details of an ebMS message.
57              
58             ebXML is a mechanism for ensuring reliable delivery of XML-based
59             messages via a transport mechanism such as SOAP. For more details on
60             ebXML, see http://www.ebxml.org/
61              
62             Large portions of this manual page are copied directly from the ebMS
63             2.0 specification.
64              
65             =cut
66              
67 1     1   27694 use base qw(Class::Tangram);
  1         3  
  1         789  
68              
69             our $VERSION = 0.03;
70              
71             =head1 PROPERTIES
72              
73             An ebMS message contains the following properties (case sensitive):
74              
75             =over
76              
77             =item B and B
78              
79             The REQUIRED B property identifies the Party that originated the
80             message. The REQUIRED B property identifies the Party that is the
81             intended recipient of the message. Both B and B can contain
82             logical identifiers, such as a DUNS number, or identifiers that also
83             imply a physical location such as an eMail address.
84              
85             The B and the B properties are references to
86             B objects. These objects have:
87              
88             =over
89              
90             =item a list of Bs
91              
92             which occurs one or more times.
93              
94             The B property has a B and content that is a string
95             value. The B indicates the domain of names to which the string
96             in the content of the B element belongs. The value of the
97             B MUST be mutually agreed and understood by each of the
98             Parties. It is RECOMMENDED that the value of the B be a URI. It
99             is further recommended that these values be taken from the EDIRA (ISO
100             6523), EDIFACT ISO 9735 or ANSI ASC X12 I05 registries.
101              
102             If the B B is B, the content of the B
103             element MUST be a URI [RFC2396], otherwise the I SHOULD
104             report an error (see section 11) with B set to
105             B and B set to B. It is strongly
106             RECOMMENDED that the content of each B be a URI.
107              
108             Cget_PartyIds()> returns a list of B
109             =E B pairs. Cset_PartyIds()>
110             accepts the same input.
111              
112             =item a list of Bs
113              
114             which occurs zero or one times
115              
116             The B property identifies the authorized role
117             (fromAuthorizedRole or toAuthorizedRole) of the Party I (when
118             present as a child of the B element) and/or I (when
119             present as a child of the B element) the message. The value of
120             each element of the B is a non-empty string, which is specified
121             in the CPA.
122              
123             =back
124              
125             If either the B or B properties contain multiple B
126             elements, all members of the list MUST identify the same organisation.
127             Unless a single B value refers to multiple identification
128             systems, a B attribute value must not appear more than once in a
129             single list of B elements.
130              
131             Note: This mechanism is particularly useful when transport of a
132             message between the parties may involve multiple intermediaries (see
133             Sections 8.5.4, Multi-hop TraceHeader Sample and 10.3, ebXML Reliable
134             Messaging Protocol). More generally, the From Party should provide
135             identification in all domains it knows in support of intermediaries
136             and destinations that may give preference to particular identification
137             systems.
138              
139             The B and B elements contain zero or one B child
140             element that, if present, SHALL immediately follow the last B
141             child element.
142              
143             The following fragment demonstrates usage of the B and B
144             elements.
145              
146            
147             123456789
148             RDWY
149            
150            
151             mailto:president.brown@california.uber.alles
152            
153              
154             This is set in a B object via the following Perl
155             fragment:
156              
157             $message->set_From
158             ( [ PartyIds => [ 'urn:duns' => "123456789",
159             'SCAC' => "RDWY", ],
160             Roles => [ "X-Originator" ],
161             ] );
162              
163             $message->set_To
164             ( [ PartyIds => [ undef => 'mailto:president.brown@california.uber.alles' ],
165             Roles => [ "X-Recipient" ],
166             ] );
167              
168              
169             =item B
170              
171             The REQUIRED B property is a string that identifies the
172             parameters governing the exchange of messages between the parties.
173             The recipient of a message MUST be able to resolve the B to an
174             individual set of parameters, taking into account the sender of the
175             message.
176              
177             The value of a B property MUST be unique within a namespace
178             that is mutually agreed by the two parties. This could be a
179             concatenation of the B and B PartyId values, a URI that is
180             prefixed with the Internet domain name of one of the parties, or a
181             namespace offered and managed by some other naming or registry
182             service. It is RECOMMENDED that the B be a URI.
183              
184             The B MAY reference an instance of a CPA as defined in the
185             ebXML Collaboration Protocol Profile and Agreement Specification
186             [ebCPP]. An example of the CPAId element follows:
187              
188             http://example.com/cpas/ourcpawithyou.xml
189              
190             This is set with the Perl fragment:
191              
192             $message->set_CPAId("http://example.com/cpas/ourcpawithyou.xml");
193              
194             If the parties are operating under a CPA, then the reliable messaging
195             parameters are determined by the appropriate elements from that CPA,
196             as identified by the B property. If a receiver determines that
197             a message is in conflict with the CPA, the appropriate handling of
198             this conflict is undefined by this specification. Therefore, senders
199             SHOULD NOT generate such messages unless they have prior knowledge of
200             the receiver's capability to deal with this conflict.
201              
202             If a receiver chooses to generate an error as a result of a detected
203             inconsistency, then it MUST report it with an B of
204             B and a severity of B. If it chooses to generate
205             an error because the B is not recognized, then it MUST report
206             it with an B of B and a severity of
207             B.
208             =item B
209              
210             The REQUIRED B property is a string identifying the
211             set of related messages that make up a conversation between two
212             Parties. It MUST be unique within the context of the specified
213             B. The I initiating a conversation determines the value
214             of the B property that SHALL be reflected in all
215             messages pertaining to that conversation.
216              
217             The B enables the recipient of a message to identify
218             the instance of an application or process that generated or handled
219             earlier messages within a conversation. It remains constant for all
220             messages within a conversation.
221              
222             The value used for a B is implementation dependent.
223             An example of the B element follows:
224              
225             20001209-133003-28572
226              
227             As set by:
228              
229             $message->set_ConversationId("20001209-133003-28572");
230              
231             Note: Implementations are free to choose how they will identify and
232             store conversational state related to a specific conversation.
233             Implementations SHOULD provide a facility for mapping between their
234             identification scheme and a B generated by another
235             implementation.
236              
237             =item B
238              
239             The REQUIRED B property identifies the service that acts on
240             the message and it is specified by the designer of the service. The
241             designer of the service may be:
242              
243             =over
244              
245             =item *
246              
247             a standards organization, or
248              
249             =item *
250              
251             an individual or enterprise
252              
253             =back
254              
255             Note: In the context of an ebXML business process model, an action
256             equates to the lowest possible role based activity in the Business
257             Process [ebBPSS] (requesting or responding role) and a service is a
258             set of related actions for an authorized role within a party.
259              
260             An example of the B element follows:
261              
262             urn:services:SupplierOrderProcessing
263              
264             Set with:
265              
266             $message->set_service("urn:services:SupplierOrderProcessing");
267              
268              
269             Note: URIs in the B element that start with the namespace
270             C are reserved for use by this
271             specification.
272              
273             The B element has a single B attribute.
274              
275             If the B attribute is present, it indicates the parties sending
276             and receiving the message know, by some other means, how to interpret
277             the content of the B element. The two parties MAY use the
278             value of the type attribute to assist in the interpretation.
279              
280             If the B attribute is not present, the content of the B
281             element MUST be a URI [RFC2396]. If it is not a URI then report an
282             error with B of B and B of
283             B.
284              
285             =item B
286              
287             The REQUIRED B element identifies a process within a
288             B that processes the Message. B SHALL be unique
289             within the B in which it is defined. The value of the
290             B element is specified by the designer of the service. An
291             example of the B element follows:
292              
293             NewOrder
294              
295             If the value of either the B or B element are
296             unrecognized by the I, then it MUST report the error
297             with an B of B and a B of
298             B.
299              
300             =item B
301              
302             The REQUIRED MessageData element provides a means of uniquely identifying an ebXML Message. It
303             contains the following:
304             · MessageId element
305             · Timestamp element
306             · RefToMessageId element
307             · TimeToLive element
308             The following fragment demonstrates the structure of the MessageData element:
309              
310            
311             20001209-133003-28572@example.com
312             2001-02-15T11:12:12
313             20001209-133003-28571@example.com
314            
315              
316             =item B
317              
318             The REQUIRED element MessageId is a globally unique identifier for each message conforming to
319             MessageId [RFC2822].
320             Note: In the Message-Id and Content-Id MIME headers, values are always surrounded by angle brackets. However
321             references in mid: or cid: scheme URI's and the MessageId and RefToMessageId elements MUST NOT include
322             these delimiters.
323              
324             =item B
325              
326             The REQUIRED Timestamp is a value representing the time that the
327             message header was created conforming to a dateTime [XMLSchema] and
328             MUST be expressed as UTC. Indicating UTC in the Timestamp element by
329             including the `Z' identifier is optional.
330              
331             =item B
332              
333             The RefToMessageId element has a cardinality of zero or one. When
334             present, it MUST contain the MessageId value of an earlier ebXML
335             Message to which this message relates. If there is no earlier related
336             message, the element MUST NOT be present.
337              
338             For Error messages, the RefToMessageId element is REQUIRED and its
339             value MUST be the MessageId value of the message in error (as defined
340             in section 4.2).
341              
342             =item B
343              
344             If the TimeToLive element is present, it MUST be used to indicate the
345             time, expressed as UTC, by which a message should be delivered to the
346             To Party MSH. It MUST conform to an XML Schema dateTime. In this
347             context, the TimeToLive has expired if the time of the internal clock,
348             adjusted for UTC, of the Receiving MSH is greater than the value of
349             TimeToLive for the message.
350              
351             If the To Party's MSH receives a message where TimeToLive has expired,
352             it SHALL send a message to the From Party MSH, reporting that the
353             TimeToLive of the message has expired. This message SHALL be
354             comprised of an ErrorList containing an error with the errorCode
355             attribute set to TimeToLiveExpired and the severity attribute set to
356             Error.
357              
358             =item B
359              
360             The DuplicateElimination element, if present, identifies a request by
361             the sender for the receiving MSH to check for duplicate messages (see
362             section 6.4.1 for more details). Valid values for
363             DuplicateElimination:
364              
365             * The Ace of spades
366              
367             Gambling is for fools, but thats the way I like it baby, I don't want
368             to live for ever.. and don't forget the joker!
369              
370             =over
371              
372             =item DuplicateElimination present
373              
374             duplicate messages SHOULD be eliminated.
375              
376             =item DuplicateElimination not present
377              
378             this results in a delivery behavior of Best-Effort. The
379             DuplicateElimination element MUST NOT be present if the CPA has
380             duplicateElimination set to never (see section 6.4.1 and section 6.6
381             for more details).
382              
383             =back
384              
385             =item B
386              
387             The Description element may be present zero or more times. Its
388             purpose is to provide a human readable description of the purpose or
389             intent of the message. The language of the description is defined by
390             a required xml:lang attribute. The xml:lang attribute MUST comply
391             with the rules for identifying anguages specified in XML [XML]. Each
392             occurrence SHOULD have a different value for xml:lang.
393              
394             An example of a Description element follows.
395              
396             Purchase Order for
397             One night in bangkok
398              
399             =item B
400              
401             The ebMS Version. This module supports version 2.0, so that is the
402             default value of this property.
403              
404             The REQUIRED version attribute indicates the version of the ebXML
405             Message Service Header Specification to which the ebXML SOAP Header
406             extensions conform. Its purpose is to provide future versioning
407             capabilities. For conformance to this specification, all of the
408             version attributes on any SOAP extension elements defined in this
409             specification MUST have a value of "2.0". An ebXML message MAY
410             contain SOAP header extension elements that have a value other than
411             "2.0". An implementation conforming to this specification that
412             receives a message with ebXML SOAP extensions qualified with a version
413             other than "2.0" MAY process the message if it recognizes the version
414             identified and is capable of processing it. It MUST respond with an
415             error (details TBD) if it does not recognize the identified version.
416              
417             The version attribute MUST be namespace qualified for the ebXML SOAP
418             Envelope extensions namespace defined above.
419              
420             Use of multiple versions of ebXML SOAP extensions elements within the
421             same ebXML SOAP document, while supported, should only be used in
422             extreme cases where it becomes necessary to semantically change an
423             element, which cannot wait for the next ebXML Message Service
424             Specification version release.
425              
426             =item B
427              
428             The Manifest element MAY be present as a child of the SOAP Body
429             element. The Manifest element is a composite element consisting of
430             one or more Reference elements. Each Reference element identifies
431             payload data associated with the message, whether included as part of
432             the message as payload document(s) contained in a Payload Container,
433             or remote resources accessible via a URL. It is RECOMMENDED that no
434             payload data be present in the SOAP Body. The purpose of the Manifest
435             is:
436              
437             =over
438              
439             =item *
440              
441             to make it easier to directly extract a particular payload associated
442             with this ebXML Message,
443              
444             =item *
445              
446             to allow an application to determine whether it can process the
447             payload without having to parse it.
448              
449             =back
450              
451             The Manifest element is comprised of the following:
452              
453             =over
454              
455             =item
456              
457             =item *
458              
459             an id attribute
460              
461             =item *
462              
463             a version attribute
464              
465             =item *
466              
467             one or more Reference elements
468              
469             =back
470             =item B
471              
472             The Reference element is a composite element consisting of the
473             following subordinate elements:
474              
475             =over
476              
477             =item *
478              
479             zero or more Schema elements ­information about the schema(s) that
480             define the instance document identified in the parent Reference
481             element
482              
483             =item *
484              
485             zero or more Description elements ­a textual description of the
486             payload object referenced by the parent
487              
488             =back
489              
490             The Reference element itself is a simple link [XLINK]. It should be
491             noted that the use of XLINK in this context is chosen solely for the
492             purpose of providing a concise vocabulary for describing an
493             association. Use of an XLINK processor or engine is NOT REQUIRED, but
494             may prove useful in certain implementations.
495              
496             The Reference element has the following attribute content in addition
497             to the element content described above:
498              
499             =over
500             =item *
501              
502             id ­an XML ID for the Reference element,
503              
504             =item *
505              
506             xlink:type ­this attribute defines the element as being an XLINK
507             simple link. It has a fixed value of 'simple',
508              
509             =item *
510              
511             xlink:href ­this REQUIRED attribute has a value that is the URI of
512             the payload object referenced. It SHALL conform to the XLINK [XLINK]
513             specification criteria for a simple link.
514              
515             =item *
516              
517             xlink:role ­this attribute identifies some resource that describes
518             the payload object or its purpose. If present, then it SHALL have a
519             value that is a valid URI in accordance with the [XLINK]
520             specification,
521              
522             =item *
523              
524             Any other namespace-qualified attribute MAY be present. A Receiving
525             MSH MAY choose to ignore any foreign namespace attributes other than
526             those defined above.
527              
528             =back
529              
530             The designer of the business process or information exchange using
531             ebXML Messaging decides what payload data is referenced by the
532             Manifest and the values to be used for xlink:role.
533              
534             =item B
535              
536             If the item being referenced has schema(s) of some kind that describe
537             it (e.g. an XML Schema, DTD and/or a database schema), then the Schema
538             element SHOULD be present as a child of the Reference element. It
539             provides a means of identifying the schema and its version defining
540             the payload object identified by the parent Reference element. The
541             Schema element contains the following attributes:
542              
543             =over
544              
545             =item location
546              
547             the REQUIRED URI of the schema
548              
549             =item version
550              
551             a version identifier of the schema
552              
553             =back
554              
555             =back
556              
557             =head2 B
558              
559             If an xlink:href attribute contains a URI that is a content id (URI
560             scheme "cid") then a MIME part with that content-id MUST be present in
561             the corresponding Payload Container of the message. If it is not, then
562             the error SHALL be reported to the From Party with an errorCode of
563             MimeProblem and a severity of Error.
564              
565             If an xlink:href attribute contains a URI, not a content id (URI
566             scheme "cid"), and the URI cannot be resolved, it is an implementation
567             decision whether to report the error. If the error is to be reported,
568             it SHALL be reported to the From Party with an errorCode of
569             MimeProblem and a severity of Error. Note: If a payload exists, which
570             is not referenced by the Manifest, that payload SHOULD be discarded.
571              
572             =cut
573              
574             use strict 'vars', 'subs';
575              
576             our $fields = {
577             string => {
578             'Version' => { init_default => "2.0", },
579             'CPAId' => { required => 1 },
580             'Action' => undef,
581             'Namespace' => { init_default => 'http://www.oasis-open.org/committees/ebxml-msg/schema/msg-header-2_0.xsd', },
582             'MessageId' => undef,
583             'RefMessageToId' => undef,
584             'Timestamp' => { init_default => \&generateTimestamp },
585             'ConversationId' => { required => 1 },
586             },
587             ref => {
588             'From' => { class => "ebXML::Message::ToFrom", },
589             'To' => { class => "ebXML::Message::ToFrom" },
590             'Service' => { class => "ebXML::Message::Service" },
591             'Manifest' => { class => "ebXML::Message::Manifest" },
592             'DuplicateElimination' => { class => "ebXML::Message::DuplicateElimination" },
593             },
594             };
595              
596             BEGIN {
597             # FIXME - should this go into Class::Tangram ?
598             my %setters = ( From => "Message::Party",
599             To => "Message::Party",
600             Service => "ebXML::Message::Service" );
601              
602             while ( my ($attrib, $class) = each %setters ) {
603             my $class = "Message::Party";
604             my $setter = "set_$attrib";
605             *{$setter} = sub {
606             my $self = shift;
607             my $val = shift;
608             if (ref $val eq "ARRAY") {
609             $val = $class->new(@$val)
610             };
611             return eval '$self->SUPER::'."$setter".'($val, @_);'
612             }
613             }
614             }
615              
616             =head1 METHODS
617              
618             Each object property has a B<$message-Eget_X> and
619             B<$message-Eset_X> method, which get and set the value,
620             respectively. You can also use the simple B<$message-EX> as a
621             getter.
622              
623             Additionally, the following methods may be called on B
624             objects:
625              
626             =over
627              
628             =item B<$message-EgetMIMEParts>
629              
630             returns a list of MIME::Entity objects built using the addPayload method
631              
632             no arguments
633              
634             =cut
635              
636             sub getMIMEParts {
637             my $self = shift;
638             my @parts = ();
639             if ($self->haveMIMEParts) {
640             @parts = values %{$self->{_sekrit}{MIME}{parts}};
641             warn "returning mimeparts\n";
642             } else {
643             warn "we have no MIMEParts!\n";
644             }
645             return @parts;
646             }
647              
648             =item B<$message-EhaveMIMEParts>
649              
650             returns the count of MIME parts currently in the payload
651              
652             I love you honeybunny.. I love you too pumpkin.. Everybody be cool this is a robbery!
653              
654             =cut
655              
656             sub haveMIMEParts {
657             my $self = shift;
658             my $count = $self->{_sekrit}{MIME}{partcount} || 0;
659             return $count;
660             }
661              
662             =item B<$message-EgetMIMEPart>
663              
664             returns a MIME::Entity object built using the addPayload method
665             based on the name given as the first and only argument
666              
667             =cut
668              
669             sub getMIMEPart {
670             my ($self,$name) = @_;
671             my $part = $self->{_sekrit}{MIME}{parts}{$name};
672             return $part;
673             }
674              
675             =item B<$message-EaddPayload>
676              
677             Adds a payload to the message - takes either a set of options and a MIME::Entity object or string or filename
678              
679             An Entity ( a MIME::Entity object ) or data (a scalar holding the mime payload content) or a path/filename
680             to an existing and accessable file (that will make up the mime payload) are required.
681              
682             Also required are SchemaLocation, and Role (these relate to the ebXML rather than MIME itself)
683              
684             optional arguments are description, Name, filename (required unless full path provided), path
685             (required unless filename provided and includes full path), version (of Schema), content-id
686              
687              
688             $name = $message->addPayload(name=>'Foo',data=>$data, 'content-id'=>'payload-d',filename=>$filename,
689             Description => 'Purchase Order for 100,000 widgets',
690             SchemaLocation=> 'http://regrep.org/gci/purchaseOrder/po.xsd',
691             Role => 'http://regrep.org/gci/purchaseOrder', Name=>'PurchaseOrder',
692             );
693              
694             or a MIME::Entity object
695              
696             $name = $message->addpayload ( Entity => $entity, Description => 'Purchase Order for 100,000 widgets',
697             SchemaLocation=> 'http://regrep.org/gci/purchaseOrder/po.xsd',
698             Role => 'http://regrep.org/gci/purchaseOrder', Name=>'PurchaseOrder',
699             );
700              
701             =cut
702              
703             sub addPayload {
704             my ($self, %options) = @_;
705             my $name;
706             $options{Entity} ||= $options{entity};
707             $options{Description} ||= 'Not Applicable';
708             $options{SchemaLocation} ||= 'default.xsd';
709             $options{SchemaVersion} ||= '1';
710             if ($options{Entity}) {
711             $options{'content-id'} ||= $options{Entity}->head->mime_attr("content-id") || generate_content_id(%options);
712             $name = $options{Entity}->head->mime_attr("content-id") || generate_content_id(%options) ;
713             } else {
714             my $id = generate_content_id(%options);
715             $name = $options{name} || $options{Name} || generate_content_id(%options);
716             my %arguments = (Disposition => "attachment", Type => "text/xml",);
717             $options{filename} ||= $options{Filename} || '$name.tmp';
718             $options{path} ||= $options{Path} || "/tmp/$options{filename}";
719             $options{data} ||= $options{Data};
720             unless ( -f $options{path} ) {
721             open (TMP,">$options{path}") or die "can't create tmp file for MIME part ( $options{path} ) : $!\n";
722             print TMP $options{data};
723             close TMP;
724             push(@{$self->{sekrit}{tmp_files}},$options{path} );
725             }
726              
727             $options{'content-id'} = $id;
728              
729             my $mime_part = MIME::Entity->build ( Path => $options{path},
730             Filename => $options{filename},
731             Id => $options{'content-id'});
732             $options{Entity} = $mime_part;
733             }
734             $self->{_sekrit}{MIME}{parts}{$name} = $options{Entity};
735             $self->{_sekrit}{MIME}{partcount}++;
736              
737             $self->Manifest->References_insert
738             ( ebXML::Message::Reference->new(
739             Description => ebXML::Message::Description->new(VALUE => $options{Description},
740             , xml_lang=> 'en-GB',),
741             Schema => ebXML::Message::Schema->new(Version => $options{SchemaVersion},
742             Location => $options{SchemaLocation}, ),
743             id => $options{'content-id'},
744             xlink_href => "cid:$options{'content-id'}",
745             xlink_role => $options{Role},
746             ), );
747              
748             return $name;
749             }
750              
751             =item B<$message-EremovePayload>
752              
753             removes a named payload from from the message, returns 1 or 0 depending
754             if present or not
755              
756             =cut
757              
758             sub removePayload {
759             my ($self, $name) = @_;
760             my $success = 0;
761             if ($self->{_sekrit}{MIME}{parts}{name}) {
762             delete $self->{_sekrit}{MIME}{parts}{name};
763             $success++;
764             }
765             return $success;
766             }
767              
768             =item B<$message-EgetOutput>
769              
770             returns one of : Xerces DOM Document object, SOAP::Data::Builder object,
771             XML (generated via Xerces / DOM), XML (generated by SOAP::Data::Builder)
772             depending on mode
773              
774             accepts one argument : mode which can be any of 'dom-xml','dom-doc',
775             'soap-xml','soap-data'
776              
777             =cut
778              
779             sub getOutput {
780             my ($self,$mode) = @_;
781             my $output;
782              
783             MODE: {
784             if (lc($mode) eq 'dom-xml') {
785             use ebXML::Message::DOMWriter;
786             $output = ebXML::Message::DOMWriter::getOutput(ebXML::Message::DOMWriter::databuilder($self));
787             last;
788             }
789             if (lc($mode) eq 'dom-doc') {
790             use ebXML::Message::DOMWriter;
791             $output = ebXML::Message::DOMWriter::databuilder($self);
792             last;
793             }
794             if (lc($mode) eq 'soap-data') {
795             use ebXML::Message::SOAPWriter;
796             $output = ebXML::Message::SOAPWriter::databuilder($self);
797             last;
798             }
799             if (lc($mode) eq 'soap-xml') {
800             use ebXML::Message::SOAPWriter;
801             $output = ebXML::Message::SOAPWriter::getOutput(ebXML::Message::SOAPWriter::databuilder($self));
802             last;
803             }
804             warn " no such mode : $mode ! \n";
805             } # end of MODE
806              
807             return $output;
808             }
809              
810             =back
811              
812             =cut
813              
814             sub DESTEROY {
815             warn "DESTEROY called\n";
816             my $self = shift;
817             if (ref $self->{sekrit}{tmp_files}) {
818             foreach my $file ( @{$self->{sekrit}{tmp_files}} ) {
819             warn "removing temp file $file \n";
820             unlink $file or warn "ERROR : unable to remove temp file ($file) : $!\n";
821             }
822             } else {
823             warn "no temporary files to clean up\n";
824             }
825             }
826              
827             #########################################################################
828              
829             sub generate_content_id {
830             my ($self,%options) = @_;
831             my $date = time;
832             my $content_id;
833             foreach my $option ( keys %options ) {
834             OPTION: {
835             if (lc $option eq 'content-id') {
836             $content_id = $options{$option};
837             last;
838             }
839             if (lc $option eq 'name') {
840             $content_id = "$options{$option}-$date";
841             last;
842             }
843             if (lc $option eq 'filename') {
844             $content_id = "$options{$option}-$date";
845             last;
846             }
847             if (lc $option eq 'path') {
848             ($content_id) = reverse (split(/[\/\\]/,$options{$option}));
849             $content_id .= "-$date";
850             last;
851             }
852             } # end of OPTION
853             }
854             return $content_id;
855             }
856              
857             sub generateTimestamp {
858             my $self = shift;
859             my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = (localtime);
860             my $timestamp = sprintf("%4d-%02d-%02dT%02s:%02s:%02d",$year+1900, $mon+1, $mday, $hour, $min, $sec);
861             # 2000-07-25T12:19:05
862             warn "timestamp : $timestamp\n";
863             if ($self) { $self->Timestamp($timestamp) unless ($self->Timestamp); }
864             return $timestamp;
865             }
866              
867             sub requiresAction {
868             my ($self,$value) = @_;
869             if ($value) { $self->{_sekrit}{requiresAction} = $value; }
870             my $yesno = $self->{_sekrit}{requiresAction} || 0;
871             return $yesno;
872             }
873              
874             #########################################################################
875             # internal / private methods
876             #########################################################################
877              
878             sub new_from_DOMDocument {
879             my ($self,$doc) = @_;
880             use ebXML::Message::DOMReader;
881             my $class = ebXML::Message::DOMReader->new($doc);
882             return $class;
883             }
884              
885             #########################################################################
886             # Subclasses for ebXML::Message
887             #########################################################################
888              
889             # ebXML::Message::Party
890             package ebXML::Message::Party;
891             use base qw(Class::Tangram);
892             our $fields = { string => [ qw(PartyId Type VALUE) ] };
893              
894             #
895             # ebXML::Message::Manifest
896             package ebXML::Message::Manifest;
897             use base qw(Class::Tangram);
898             our $fields = { string => [ qw(id Version ) ], set => { References => { class => "ebXML::Message::Reference"} },};
899              
900             #
901             # ebXML::Message::Description
902             package ebXML::Message::Description;
903             use base qw(Class::Tangram);
904             our $fields = { string => [ qw(VALUE xml_lang) ] };
905              
906             #
907             # ebXML::Message::Schema
908             package ebXML::Message::Schema;
909             use base qw(Class::Tangram);
910             our $fields = { string => [qw(Version Location)] };
911              
912             #
913             # ebXML::Message::DuplicateElimination
914             package ebXML::Message::DuplicateElimination;
915             use base qw(Class::Tangram);
916             our $fields = { string => [qw(VALUE foo bar)] };
917              
918             #
919             # ebXML::Message::ToFrom
920             package ebXML::Message::ToFrom;
921             use base qw(Class::Tangram);
922             our $fields = { set => { Roles => { class => "ebXML::Message::Role" }, Partys => { class => "ebXML::Message::Party" } } };
923             #
924             # ebXML::Message::Role
925             package ebXML::Message::Role;
926             use base qw(Class::Tangram);
927             our $fields = { string => [ qw(VALUE)] };
928              
929             ###################################################################
930              
931             =head1 EXAMPLES
932              
933             =over
934              
935             =item MessageHeader
936              
937             The following fragment demonstrates the structure of the MessageHeader
938             element within the SOAP Header:
939              
940            
941             SOAP:mustUnderstand="1">
942            
943             uri:example.com
944             http://rosettanet.org/roles/Buyer
945            
946            
947             QRS543
948             http://rosettanet.org/roles/Seller
949            
950             http://www.oasis-open.org/cpa/123456
951             987654321
952             QuoteToCollect
953             NewPurchaseOrder
954            
955             UUID-2
956             2000-07-25T12:19:05
957             UUID-1
958            
959            
960            
961              
962             =item B
963              
964             The following fragment demonstrates a typical Manifest for a single payload MIME body part:
965              
966            
967            
968             xlink:href="cid:payload-1"
969             xlink:role="http://regrep.org/gci/purchaseOrder">
970            
971             eb:version="2.0"/>
972             Purchase Order for
973             100,000 widgets
974            
975            
976              
977             =back
978              
979              
980             =cut
981              
982             ###################################################################
983             ###################################################################
984              
985             1;