File Coverage

blib/lib/POE/Event/Message/Header.pm
Criterion Covered Total %
statement 12 108 11.1
branch 0 60 0.0
condition 0 51 0.0
subroutine 4 35 11.4
pod 7 30 23.3
total 23 284 8.1


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # File: POE/Event/Message/Header.pm
4             # Desc: A generic network message header class to use as a starting point.
5             # Date: Mon Oct 10 10:10:59 2005
6             # Stat: Prototype, Experimental
7             #
8             package POE::Event::Message::Header;
9 3     3   48 use 5.006;
  3         10  
  3         123  
10 3     3   15 use strict;
  3         7  
  3         81  
11 3     3   15 use warnings;
  3         6  
  3         142  
12              
13             our $PACK = __PACKAGE__;
14             our $VERSION = '0.04';
15             ### @ISA = qw( );
16              
17             ### POE::Kernel; ## Don't use POE here!
18 3     3   1739 use POE::Event::Message::UniqueID;
  3         9  
  3         31  
19              
20             my $IdClass = "POE::Event::Message::UniqueID";
21              
22             sub new
23 0     0 1   { my($self,$hRef) = @_;
24              
25 0   0       $self = bless {}, ref($self)||$self;
26              
27 0 0 0       if ($hRef and $hRef =~ /HASH/) {
28 0           foreach (keys %$hRef) { $self->{$_} = $hRef->{$_} }
  0            
29              
30 0 0 0       $self->set('r2id', $self->id() ||0 ) unless $self->r2id();
31              
32             } else {
33              
34             # $self->set('r2id', undef ); # InResponseTo message id
35             # $self->set('ttl', undef ); # message TimeToLive
36             # $self->set('type', undef ); # message type
37             }
38              
39 0           $self->set('id', $IdClass->generate() ); # guaranteed unique message id
40              
41 0           return $self;
42             }
43              
44 0     0 1   sub set { $_[0]->{$_[1]}=$_[2] } # Note that the 'param' method
45 0   0 0 1   sub get { return( $_[0]->{$_[1]}||"" ) } # combines 'set' and 'get'
46 0 0 0 0 0   sub param { $_[2] ? $_[0]->{$_[1]}=$_[2] : return( $_[0]->{$_[1]}||"" ) }
47 0   0 0 0   sub setErr { return( $_[0]->{STATUS}=$_[1]||0, $_[0]->{ERROR}=$_[2]||"" ) }
      0        
48 0   0 0 0   sub status { return( $_[0]->{STATUS}||0, $_[0]->{ERROR}||"" ) }
      0        
49 0 0 0 0 0   sub stat { ( wantarray ? ($_[0]->{ERROR}||"") : ($_[0]->{STATUS} ||0) ) }
      0        
50 0   0 0 0   sub err { return($_[0]->{ERROR}||"") }
51 0     0 1   sub del { delete $_[0]->{$_[1]} }
52              
53             *delete = \&del;
54             *reset = \&del;
55              
56 0     0 0   sub id { $_[0]->get('id') } # unique message ID
57 0     0 0   sub r2id { $_[0]->get('r2id') } # orig. msg ID, in a response
58 0     0 0   sub ttl { $_[0]->param('ttl', $_[1]) } # message time-to-live
59 0     0 0   sub type { $_[0]->param('type', $_[1]) } # message type (reply | bcast)
60 0     0 0   sub mode { $_[0]->param('mode', $_[1]) } # response mode (post | call)
61              
62             *rid = \&r2id;
63             *origId = \&r2id;
64              
65             *setType = \&type; # Type: reply or bcast (default: reply)
66             *getType = \&type; # Type: reply or bcast (default: reply)
67              
68             *setMode = \&mode; # Mode: post or call (default: post)
69             *getMode = \&mode; # Mode: post or call (default: post)
70              
71             #-----------------------------------------------------------------------
72             # Self routing messages without CODE refs, suitable for Filtering.
73             # Keep first implementation simple (if you call allowing multiple
74             # "RouteBack" destinations simple :-), and anticipate extensions.
75             #
76             # $message->header->addRouteBack( $mode, $service, $event, @args );
77             #
78             # $mode defaults to "post",
79             # $service defaults to "current_active",
80             # and "initial state" @args are optionsl
81              
82             # NOTE: these are LIFO stacks, and are "pushed" when "add" methods are
83             # used and "popped" when "del" methods are used. See the "Message"
84             # class for the various methods that make use of these stacks.
85              
86 0     0 1   sub addRouteTo { shift->_addRouting( "RouteTo", undef, undef, @_ ) }
87 0     0 1   sub addRouteBack { shift->_addRouting( "RouteBack", undef, undef, @_ ) }
88 0     0 0   sub addRemoteRouteTo { shift->_addRouting( "RouteTo", @_ ) }
89 0     0 0   sub addRemoteRouteBack { shift->_addRouting( "RouteBack", @_ ) }
90              
91             sub _addRouting
92 0     0     { my($self, $type, $host, $port, $mode, $service, $event, @args) = @_;
93              
94 0 0         if ($type !~ /^Route(To|Back)$/) {
95 0           return $self->setErr(-1, "unknown 'type' ($type) in 'addRouting' method of '$PACK'");
96              
97             }
98              
99 0   0       $host ||= "";
100 0   0       $port ||= "";
101             # $mode ||= "post";
102 0 0 0       ( $mode = $self->mode() || "post" ) unless ( $mode );
103              
104 0 0 0       if ($host and $port) {
    0          
105 0   0       $service ||= "command";
106 0   0       $event ||= "dispatch";
107              
108             } elsif (! $service ) {
109 0 0         if (! defined $INC{'POE/Kernel.pm'}) {
110 0           return $self->setErr(-1, "'POE::Kernel' module is not loaded in 'addRouteBack' method of '$PACK'");
111              
112             } else {
113 0           $service = POE::Kernel->get_active_session()->ID();
114             }
115             }
116              
117             ## warn "DEBUG: _addRouting: type='$type' mode='$mode' service='$service' event='$event'\n";
118              
119 0 0 0       if (! ($service and $event) ) {
120 0           return $self->setErr(-1, "missing 'service' and/or 'event' argument in 'addRouting' method of '$PACK'");
121             }
122              
123 0           unshift @{ $self->{$type} }, [ $host,$port, $mode,$service,$event,@args ];
  0            
124 0           return;
125             }
126              
127             *unshiftRouteTo = \&addRouteTo; # add a RouteTo
128             *shiftRouteTo = \&delRouteTo; # del a RouteTo
129              
130             *unshiftRouteBack = \&addRouteBack; # add a RouteBack
131             *shiftRouteBack = \&delRouteBack; # del a Routeback
132              
133             # FIX: syntax for "delRoute*" is clumsy when the lists are empty.
134              
135 0 0   0 0   sub delRouteTo { @{ (shift @{ $_[0]->{RouteTo} } ||[]) } }
  0            
  0            
136 0 0   0 0   sub delRouteBack { @{ (shift @{ $_[0]->{RouteBack} } ||[]) } }
  0            
  0            
137              
138 0 0   0 0   sub hasRouting { ( ($_[0]->hasRouteTo()) || ($_[0]->hasRouteBack()) ) }
139              
140             *getRouting = \&hasRouting;
141             *getRouteTo = \&hasRouteTo;
142             *getRouteBack = \&hasRouteBack;
143              
144             sub hasRouteTo
145 0     0 0   { my($self, $type) = @_;
146 0 0         return undef unless (defined $self->{"RouteTo"});
147 0           return( $self->{'RouteTo'}->[ 0 ] );
148             }
149              
150             sub hasRouteBack
151 0     0 0   { my($self) = @_;
152 0 0         return undef unless (defined $self->{"RouteBack"});
153 0           return( $self->{'RouteBack'}->[ 0 ] );
154             }
155              
156             sub nextRouteType
157 0     0 0   { my($self) = @_;
158              
159 0   0       my $nextRoute = $self->hasRouteTo() || $self->hasRouteBack();
160              
161 0 0 0       return "remote" if ($nextRoute->[0] and $nextRoute->[1]);
162 0 0         return "" unless $nextRoute->[2];
163 0 0         return "post" if ($nextRoute->[2] =~ /^post/i);
164 0 0         return "call" if ($nextRoute->[2] =~ /^call/i);
165 0           return "";
166             }
167              
168 0 0   0 0   sub nextRouteIsRemote { ($_[0]->nextRouteType() eq "remote" ? 1 : 0) }
169 0 0   0 0   sub nextRouteIsLocal { ($_[0]->nextRouteType() =~ /(post|call)/ ? 1 : 0) }
170 0 0   0 0   sub nextRouteIsPost { ($_[0]->nextRouteType() eq "post" ? 1 : 0) }
171 0 0   0 0   sub nextRouteIsCall { ($_[0]->nextRouteType() eq "call" ? 1 : 0) }
172              
173             #-----------------------------------------------------------------------
174              
175             sub dump {
176 0     0 1   my($self,$nohead)= @_;
177 0           my($pack,$file,$line)=caller();
178 0           my $text = "";
179 0 0         unless ($nohead) {
180 0           $text .= "DEBUG: ($PACK\:\:dump)\n self='$self'\n";
181 0           $text .= "CALLER $pack at line $line\n ($file)\n";
182             }
183 0           my $value;
184 0           foreach my $param (sort keys %$self) {
185 0           $value = $self->{$param};
186 0           $value = $self->zeroStr( $value, "" ); # handles value of "0"
187 0           $text .= " $param = $value\n";
188             # Kinda kludgy, might wanna fix this next bit.
189 0 0         if ($param =~ /^Route(To|Back)$/) {
190 0 0         my $arrow = ( $param eq "RouteTo" ? "-->" : "<--" );
191 0 0         if (! @$value) {
192 0           $text .= " $arrow ((empty list))\n";
193 0           next;
194             }
195 0           foreach my $route (@$value) {
196 0           $text .= " $arrow '";
197 0           foreach my $arg (@$route) {
198 0 0         $text .= ( $arg ? "$arg', '" : "', '" );
199             }
200 0           chop($text); chop($text); chop($text);
  0            
  0            
201             }
202 0           $text .= "\n"
203             }
204             }
205 0           $text .= "_" x 25 ."\n";
206 0           return($text);
207             }
208              
209             sub zeroStr
210 0     0 0   { my($self,$value,$undef) = @_;
211 0 0         return $undef unless defined $value;
212 0 0 0       return "0" if (length($value) and ! $value);
213 0           return $value;
214             }
215             #_________________________
216             1; # Required by require()
217              
218             __END__