| line | stmt | bran | cond | sub | pod | time | code | 
| 1 | 3 |  |  | 3 |  | 86304 | use 5.006; | 
|  | 3 |  |  |  |  | 23 |  | 
| 2 | 3 |  |  | 3 |  | 16 | use warnings; | 
|  | 3 |  |  |  |  | 4 |  | 
|  | 3 |  |  |  |  | 103 |  | 
| 3 | 3 |  |  | 3 |  | 16 | use strict; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 155 |  | 
| 4 |  |  |  |  |  |  | package Email::Abstract; | 
| 5 |  |  |  |  |  |  | # ABSTRACT: unified interface to mail representations | 
| 6 |  |  |  |  |  |  | $Email::Abstract::VERSION = '3.009'; | 
| 7 | 3 |  |  | 3 |  | 19 | use Carp; | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 196 |  | 
| 8 | 3 |  |  | 3 |  | 1041 | use Email::Simple; | 
|  | 3 |  |  |  |  | 9644 |  | 
|  | 3 |  |  |  |  | 92 |  | 
| 9 | 3 |  |  | 3 |  | 1568 | use MRO::Compat; | 
|  | 3 |  |  |  |  | 5599 |  | 
|  | 3 |  |  |  |  | 184 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | use Module::Pluggable 1.5 | 
| 12 | 3 |  |  |  |  | 23 | search_path => [__PACKAGE__], | 
| 13 |  |  |  |  |  |  | except      => 'Email::Abstract::Plugin', | 
| 14 | 3 |  |  | 3 |  | 1730 | require     => 1; | 
|  | 3 |  |  |  |  | 35762 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 | 3 |  |  | 3 |  | 304 | use Scalar::Util (); | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 1545 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | my @plugins = __PACKAGE__->plugins(); # Requires them. | 
| 19 |  |  |  |  |  |  | my %adapter_for = | 
| 20 |  |  |  |  |  |  | map  { $_->target => $_ } | 
| 21 |  |  |  |  |  |  | grep { | 
| 22 |  |  |  |  |  |  | my $avail = eval { $_->is_available }; | 
| 23 |  |  |  |  |  |  | $@ ? ($@ =~ /Can't locate object method "is_available"/) : $avail; | 
| 24 |  |  |  |  |  |  | } | 
| 25 |  |  |  |  |  |  | @plugins; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | sub object { | 
| 28 | 82 |  |  | 82 | 1 | 146 | my ($self) = @_; | 
| 29 | 82 | 100 |  |  |  | 244 | return unless ref $self; | 
| 30 | 37 |  |  |  |  | 102 | return $self->[0]; | 
| 31 |  |  |  |  |  |  | } | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | sub new { | 
| 34 | 13 |  |  | 13 | 1 | 31842 | my ($class, $foreign) = @_; | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 13 | 100 |  |  |  | 23 | return $foreign if eval { $foreign->isa($class) }; | 
|  | 13 |  |  |  |  | 136 |  | 
| 37 |  |  |  |  |  |  |  | 
| 38 | 11 | 100 |  |  |  | 64 | $foreign = Email::Simple->new($foreign) | 
| 39 |  |  |  |  |  |  | unless Scalar::Util::blessed($foreign); | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 11 |  |  |  |  | 2343 | my $adapter = $class->__class_for($foreign); # dies if none available | 
| 42 | 9 |  |  |  |  | 32 | return bless [ $foreign, $adapter ] => $class; | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | sub __class_for { | 
| 46 | 61 |  |  | 61 |  | 10384 | my ($self, $foreign, $method, $skip_super) = @_; | 
| 47 | 61 |  | 100 |  |  | 253 | $method ||= 'handle'; | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 61 |  |  |  |  | 92 | my $f_class = ref $foreign; | 
| 50 | 61 | 100 |  |  |  | 125 | $f_class = $foreign unless $f_class; | 
| 51 |  |  |  |  |  |  |  | 
| 52 | 61 | 100 | 100 |  |  | 271 | return $f_class if ref $foreign and $f_class->isa($self); | 
| 53 |  |  |  |  |  |  |  | 
| 54 | 49 | 100 |  |  |  | 155 | return $adapter_for{$f_class} if $adapter_for{$f_class}; | 
| 55 |  |  |  |  |  |  |  | 
| 56 | 5 | 100 |  |  |  | 14 | if (not $skip_super) { | 
| 57 | 4 |  |  |  |  | 8 | my @bases = @{ mro::get_linear_isa($f_class) }; | 
|  | 4 |  |  |  |  | 18 |  | 
| 58 | 4 |  |  |  |  | 8 | shift @bases; | 
| 59 | 4 |  |  |  |  | 10 | for my $base (@bases) { | 
| 60 | 3 | 100 |  |  |  | 15 | return $adapter_for{$base} if $adapter_for{$base}; | 
| 61 |  |  |  |  |  |  | } | 
| 62 |  |  |  |  |  |  | } | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 3 |  |  |  |  | 370 | Carp::croak "Don't know how to $method $f_class"; | 
| 65 |  |  |  |  |  |  | } | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | sub _adapter_obj_and_args { | 
| 68 | 70 |  |  | 70 |  | 108 | my $self = shift; | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 70 | 100 |  |  |  | 139 | if (my $thing = $self->object) { | 
| 71 | 25 |  |  |  |  | 93 | return ($self->[1], $thing, @_); | 
| 72 |  |  |  |  |  |  | } else { | 
| 73 | 45 |  |  |  |  | 81 | my $thing   = shift; | 
| 74 | 45 | 100 |  |  |  | 161 | my $adapter = $self->__class_for( | 
| 75 |  |  |  |  |  |  | Scalar::Util::blessed($thing) ? $thing : 'Email::Simple' | 
| 76 |  |  |  |  |  |  | ); | 
| 77 | 45 |  |  |  |  | 163 | return ($adapter, $thing, @_); | 
| 78 |  |  |  |  |  |  | } | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | for my $func (qw(get_header get_body set_header set_body as_string)) { | 
| 82 | 3 |  |  | 3 |  | 24 | no strict 'refs'; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 882 |  | 
| 83 |  |  |  |  |  |  | *$func = sub { | 
| 84 | 66 |  |  | 66 |  | 35567 | my $self = shift; | 
| 85 | 66 |  |  |  |  | 170 | my ($adapter, $thing, @args) = $self->_adapter_obj_and_args(@_); | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | # In the event of Email::Abstract->get_body($email_abstract), convert | 
| 88 |  |  |  |  |  |  | # it into an object method call. | 
| 89 | 66 | 100 |  |  |  | 114 | $thing = $thing->object if eval { $thing->isa($self) }; | 
|  | 66 |  |  |  |  | 394 |  | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | # I suppose we could work around this by leaving @_ intact and assigning to | 
| 92 |  |  |  |  |  |  | # it.  That seems ... not good. -- rjbs, 2007-07-18 | 
| 93 | 66 | 100 |  |  |  | 206 | unless (Scalar::Util::blessed($thing)) { | 
| 94 | 10 | 100 |  |  |  | 574 | Carp::croak "can't alter string in place" if substr($func, 0, 3) eq 'set'; | 
| 95 |  |  |  |  |  |  | $thing = Email::Simple->new( | 
| 96 | 6 | 100 |  |  |  | 20 | ref $thing ? \do{my$str=$$thing} : $thing | 
|  | 3 |  |  |  |  | 15 |  | 
| 97 |  |  |  |  |  |  | ); | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 62 |  |  |  |  | 2501 | return $adapter->$func($thing, @args); | 
| 101 |  |  |  |  |  |  | }; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | sub cast { | 
| 105 | 4 |  |  | 4 | 1 | 3671 | my $self = shift; | 
| 106 | 4 |  |  |  |  | 14 | my ($from_adapter, $from, $to) = $self->_adapter_obj_and_args(@_); | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 4 |  |  |  |  | 24 | my $adapter = $self->__class_for($to, 'construct', 1); | 
| 109 |  |  |  |  |  |  |  | 
| 110 | 3 | 100 |  |  |  | 10 | my $from_string = ref($from) ? $from_adapter->as_string($from) : $from; | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 3 |  |  |  |  | 137 | return $adapter->construct($from_string); | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | 1; | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | =pod | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | =encoding UTF-8 | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | =head1 NAME | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | Email::Abstract - unified interface to mail representations | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | =head1 VERSION | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  | version 3.009 | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | my $message = Mail::Message->read($rfc822) | 
| 132 |  |  |  |  |  |  | || Email::Simple->new($rfc822) | 
| 133 |  |  |  |  |  |  | || Mail::Internet->new([split /\n/, $rfc822]) | 
| 134 |  |  |  |  |  |  | || ... | 
| 135 |  |  |  |  |  |  | || $rfc822; | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | my $email = Email::Abstract->new($message); | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | my $subject = $email->get_header("Subject"); | 
| 140 |  |  |  |  |  |  | $email->set_header(Subject => "My new subject"); | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | my $body = $email->get_body; | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | $rfc822 = $email->as_string; | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | my $mail_message = $email->cast("Mail::Message"); | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | C provides module writers with the ability to write | 
| 151 |  |  |  |  |  |  | simple, representation-independent mail handling code. For instance, in the | 
| 152 |  |  |  |  |  |  | cases of C or C, a key part of the code | 
| 153 |  |  |  |  |  |  | involves reading the headers from a mail object. Where previously one would | 
| 154 |  |  |  |  |  |  | either have to specify the mail class required, or to build a new object from | 
| 155 |  |  |  |  |  |  | scratch, C can be used to perform certain simple operations on | 
| 156 |  |  |  |  |  |  | an object regardless of its underlying representation. | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | C currently supports C, C, | 
| 159 |  |  |  |  |  |  | C, C, C, and C.  Other | 
| 160 |  |  |  |  |  |  | representations are encouraged to create their own C class | 
| 161 |  |  |  |  |  |  | by copying C.  All modules installed under the | 
| 162 |  |  |  |  |  |  | C hierarchy will be automatically picked up and used. | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | =head1 PERL VERSION SUPPORT | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | This module has a long-term perl support period.  That means it will not | 
| 167 |  |  |  |  |  |  | require a version of perl released fewer than five years ago. | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | Although it may work on older versions of perl, no guarantee is made that the | 
| 170 |  |  |  |  |  |  | minimum required version will not be increased.  The version may be increased | 
| 171 |  |  |  |  |  |  | for any reason, and there is no promise that patches will be accepted to lower | 
| 172 |  |  |  |  |  |  | the minimum required perl. | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | =head1 METHODS | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | All of these methods may be called either as object methods or as class | 
| 177 |  |  |  |  |  |  | methods.  When called as class methods, the email object (of any class | 
| 178 |  |  |  |  |  |  | supported by Email::Abstract) must be prepended to the list of arguments, like | 
| 179 |  |  |  |  |  |  | so: | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | my $return = Email::Abstract->method($message, @args); | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | This is provided primarily for backwards compatibility. | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =head2 new | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | my $email = Email::Abstract->new($message); | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | Given a message, either as a string or as an object for which an adapter is | 
| 190 |  |  |  |  |  |  | installed, this method will return a Email::Abstract object wrapping the | 
| 191 |  |  |  |  |  |  | message. | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | If the message is given as a string, it will be used to construct an object, | 
| 194 |  |  |  |  |  |  | which will then be wrapped. | 
| 195 |  |  |  |  |  |  |  | 
| 196 |  |  |  |  |  |  | =head2 get_header | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | my $header  = $email->get_header($header_name); | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | my @headers = $email->get_header($header_name); | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  | This returns the values for the given header.  In scalar context, it returns | 
| 203 |  |  |  |  |  |  | the first value. | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =head2 set_header | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | $email->set_header($header => @values); | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | This sets the C<$header> header to the given one or more values. | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | =head2 get_body | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | my $body = $email->get_body; | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | This returns the body as a string. | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | =head2 set_body | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | $email->set_body($string); | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | This changes the body of the email to the given string. | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | B  You probably don't want to call this method, despite what you may | 
| 224 |  |  |  |  |  |  | think.  Email message bodies are complicated, and rely on things like content | 
| 225 |  |  |  |  |  |  | type, encoding, and various MIME requirements.  If you call C on a | 
| 226 |  |  |  |  |  |  | message more complicated than a single-part seven-bit plain-text message, you | 
| 227 |  |  |  |  |  |  | are likely to break something.  If you need to do this sort of thing, you | 
| 228 |  |  |  |  |  |  | should probably use a specific message class from end to end. | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | This method is left in place for backwards compatibility. | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | =head2 as_string | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | my $string = $email->as_string; | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | This returns the whole email as a decoded string. | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =head2 cast | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | my $mime_entity = $email->cast('MIME::Entity'); | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | This method will convert a message from one message class to another.  It will | 
| 243 |  |  |  |  |  |  | throw an exception if no adapter for the target class is known, or if the | 
| 244 |  |  |  |  |  |  | adapter does not provide a C method. | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | =head2 object | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | my $message = $email->object; | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | This method returns the message object wrapped by Email::Abstract.  If called | 
| 251 |  |  |  |  |  |  | as a class method, it returns false. | 
| 252 |  |  |  |  |  |  |  | 
| 253 |  |  |  |  |  |  | Note that, because strings are converted to message objects before wrapping, | 
| 254 |  |  |  |  |  |  | this method will return an object when the Email::Abstract was constructed from | 
| 255 |  |  |  |  |  |  | a string. | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | =head1 AUTHORS | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | =over 4 | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | =item * | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | Ricardo SIGNES | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | =item * | 
| 266 |  |  |  |  |  |  |  | 
| 267 |  |  |  |  |  |  | Simon Cozens | 
| 268 |  |  |  |  |  |  |  | 
| 269 |  |  |  |  |  |  | =item * | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | Casey West | 
| 272 |  |  |  |  |  |  |  | 
| 273 |  |  |  |  |  |  | =back | 
| 274 |  |  |  |  |  |  |  | 
| 275 |  |  |  |  |  |  | =head1 CONTRIBUTORS | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | =for stopwords Dave Rolsky Ricardo Signes William Yardley | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | =over 4 | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | =item * | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | Dave Rolsky | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | =item * | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | Ricardo Signes | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | =item * | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | William Yardley | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | =back | 
| 294 |  |  |  |  |  |  |  | 
| 295 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | This software is copyright (c) 2004 by Simon Cozens. | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | This is free software; you can redistribute it and/or modify it under | 
| 300 |  |  |  |  |  |  | the same terms as the Perl 5 programming language system itself. | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | =cut | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | __END__ |