
=head1 NAME

Mail::Message - general message object

=head1 CLASS INHERITANCE

 Mail::Message has extra code in
   Mail::Message::Construct

 Mail::Message
   is a Mail::Reporter

 Mail::Message is extended by
   Mail::Box::Message
   Mail::Message::Dummy
   Mail::Message::Part

=head1 SYNOPSIS

 use Mail::Box::Manager;
 my $mgr    = Mail::Box::Manager->new;
 my $folder = $mgr->open(folder => 'InBox');
 my $msg    = $folder->message(2);    # $msg is a Mail::Message now

 my $subject = $msg->subject;         # The message's subject
 my @cc      = $msg->cc;              # List of Mail::Address'es

 my $msg       = Mail::Message->build(...);
 my $reply_msg = Mail::Message->reply(...);
 my $frwd_msg  = Mail::Message->forward(...);

 my Mail::Message::Head $head = $msg->head;
 my Mail::Message::Body $body = $msg->decoded;
 $msg->decoded->print($outfile);

=head1 DESCRIPTION

A Mail::Message object is a container for MIME-encoded message information,
as defined by RFC2822.  Everything what is not specificly related to storing
the messages in mailboxes (folders) is implemented in this class.  Methods
which are are related to folders is implemented in the Mail::Box::Message
extension.

The main methods are get(), to get information from a message header field,
and decoded() to get the intended content of a message.  But there
are many more which can assist your program.

Complex message handling (like construction of replies) are implemented in the
Mail::Message::Construct package which is autoloaded into this class.  This
means you can simply use these methods as if they are part of this class.
That package adds functionality to all kinds of Mail::Message objects.

=head2 Structure of a Message

A MIME-compliant message is build upon two parts: the I<head> and the
I<body>.  The body contains the I<payload>: the data to be transfered.  The
data can be encoded, only accessible with a specific application, and may use
some weird character-set, like Vietnamese; the Mail::Box module tries to
assist you with handling these e-mails without the need to know all the
detauls.  This additional information (I<meta-information>) about the
body data is stored in the header.

The header is a list of fields, some spanning more than one line (I<folded>)
each telling something about the message. Information stored in here are for
instance the sender of the message, the receivers of the message, when it
was transported, how it was transported, etc etc.  Headers can grow quite
large.

=head2 Implementation

In Mail::Box, each message object manages exactly one header object
(a Mail::Message::Head) and one body object (a Mail::Message::Body).
See the methods in Mail::Message::Construct if you want to do complicated
things.

Mail::Box is as lazy as possible.  Whenever you open a folder, it tries
to avoid processing the messages within that folder.  In stead of parsing
(decoding) the messages when the folder is opened, they are parsed the
moment they are used for the first time.  In Mail::Box, this is called
I<delayed loading>.

=head1 METHODS

=head2 Initiation

=over 4

=item B<new> OPTIONS

(Class method)

 OPTION               DEFAULT
 body                 undef
 body_type            'Mail::Message::Body::Lines'
 field_type           undef
 head                 undef
 head_type            'Mail::Message::Head::Complete'
 log                  'WARNINGS'
 messageId            undef
 modified             <false>
 trace                'WARNINGS'
 trusted              <false>

=over 4

=item B<body> =E<gt> OBJECT

Instantiate the message with a body which has been created somewhere
before the message is constructed.  The OBJECT must be a sub-class
of Mail::Message::Body.  See also body() and storeBody().

=item B<body_type> =E<gt> CLASS

Default type of body to be created for readBody().

=item B<field_type> =E<gt> CLASS

=item B<head> =E<gt> OBJECT

Instantiate the message with a head which has been created somewhere
before the message is constructed.  The OBJECT must be a (sub-)class
of Mail::Message::Head. See also head().

=item B<head_type> =E<gt> CLASS

Default type of head to be created for readHead().

=item B<log> =E<gt> LEVEL

See Mail::Reporter::new(log)

=item B<messageId> =E<gt> STRING

The id on which this message can be recognized.  If none specified and
not defined in the header --but one is needed-- there will be one assigned
to the message to be able to pass unique message-ids between objects.

=item B<modified> =E<gt> BOOLEAN

Flags this message as being modified from the beginning on.  Usually,
modification is auto-detected, but there may be reasons to be extra
explicit.

=item B<trace> =E<gt> LEVEL

See Mail::Reporter::new(trace)

=item B<trusted> =E<gt> BOOLEAN

Is this message from a trusted source?  If not, the content must be
checked before use.  This checking will be performed when the
body data is decoded or used for transmission.

=back

=back

=head2 Constructing a Message

=over 4

=item B<bounce> [RG-OBJECT|OPTIONS]

See Mail::Message::Construct::bounce()

=item B<build> [MESSAGE|BODY], CONTENT

See Mail::Message::Construct::build()

=item B<buildFromBody> BODY, [HEAD], HEADERS

See Mail::Message::Construct::buildFromBody()

=item B<coerce> MESSAGE

(Class method) 
Coerce a MESSAGE into a Mail::Message.  In some
occasions, for instance where you add a message to a folder, this
coercion is automatically called to ensure that the correct message
type is stored.

The coerced message is returned on success, otherwise C<undef>.  The
coerced message may be a reblessed version of the original message
or a new object.  In case the message has to be specialized, for
instance from a general Mail::Message into a Mail::Box::Mbox::Message,
no copy is needed.  However, to coerce a Mail::Internet object into
a Mail::Message, a lot of copying and converting will take place.

Valid MESSAGEs which can be coerced into Mail::Message objects
are of type

=over 4

=item * Any type of Mail::Box::Message

=item * MIME::Entity's, using Mail::Message::Convert::MimeEntity

=item * Mail::Internet's, using Mail::Message::Convert::MailInternet

=back

Mail::Message::Part's, which are extensions of Mail::Message's,
can also be coerced directly from a Mail::Message::Body.

Examples:

 my $folder  = Mail::Box::Mbox->new;
 my $message = Mail::Message->build(...);

 my $coerced = Mail::Box::Mbox::Message->coerce($message);
 $folder->addMessage($coerced);

Simpler replacement for the previous two lines:

 my $coerced = $folder->addMessage($message);

=item B<forward> OPTIONS

See Mail::Message::Construct::forward()

=item B<forwardPostlude> 

See Mail::Message::Construct::forwardPostlude()

=item B<forwardPrelude> 

See Mail::Message::Construct::forwardPrelude()

=item B<forwardSubject> STRING

See Mail::Message::Construct::forwardSubject()

=item B<read> FILEHANDLE|SCALAR|REF-SCALAR|ARRAY-OF-LINES, OPTIONS

See Mail::Message::Construct::read()

=item B<reply> OPTIONS

See Mail::Message::Construct::reply()

=item B<replyPrelude> [STRING|FIELD|ADDRESS]

See Mail::Message::Construct::replyPrelude()

=item B<replySubject> STRING

See Mail::Message::Construct::replySubject()

=back

=head2 The Message

=over 4

=item B<clone> 

Create a copy of this message.  Returned is a Mail::Message object.
The head and body, the log and trace levels are taken.  Labels are
copied with the message, but the delete and modified flags are not.
 
BE WARNED: the clone of any kind of message (or a message part) will B<always
be a Mail::Message> object.  For example, a Mail::Box::Message's clone is
detached from the folder of its original.  When you use Mail::Box::addMessage()
with the cloned message at hand, then the clone will automatically
be coerced into the right message type to be added.

See also copyTo() and moveTo().

Examples:

 $copy = $msg->clone;

=item B<container> 

If the message is a part of another message, C<container> returns the
reference to the containing body.

Examples:

 my Mail::Message $msg = ...
 return unless $msg->body->isMultipart;
 my $part   = $msg->body->part(2);

 return unless $part->body->isMultipart;
 my $nested = $part->body->part(3);

 $nested->container;  # returns $msg->body
 $nested->toplevel;   # returns $msg
 $msg->container;     # returns undef
 $msg->toplevel;      # returns $msg
 $msg->isPart;        # returns false
 $part->isPart;       # returns true

=item B<isDummy> 

Dummy messages are used to fill holes in linked-list and such, where only
a message-id is known, but not the place of the header of body data.

This method is also available for Mail::Message::Dummy objects, where
this will return C<true>.  On any extension of Mail::Message, this will
return C<false>.

=item B<isModified> 

Returns whether this message is flagged as being modified.  Modifications
are changes in header lines, when a new body is set to the message
(dangerous), or when labels change.

=item B<isPart> 

Returns true if the message is a part of another message.  This is
the case for Mail::Message::Part extensions of Mail::Message.

=item B<messageId> 

Retrieve the message's id.  Every message has a unique message-id.  This id
is used mainly for recognizing discussion threads.

=item B<modified> [BOOLEAN]

Returns (optionally after setting) whether this message is flagged as
being modified.  See isModified().

=item B<print> [FILEHANDLE]

Print the message to the FILE-HANDLE, which defaults to the selected
filehandle, without the encapsulation sometimes required by a folder
type, like write() does.

Examples:

 $message->print(\*STDERR);  # to the error output
 $message->print;            # to the selected file

 my $out = IO::File->new('out', 'w');
 $message->print($out);      # no encapsulation: no folder
 $message->write($out);      # with encapsulation: is folder.

=item B<send> [MAILER], OPTIONS

Transmit the message to anything outside this Perl program.  MAILER
is a Mail::Transport::Send object.  When the MAILER is not specified, one
will be created, and kept as default for the next messages as well.

The OPTIONS are mailer specific, and a mixture of what is usable for
the creation of the mailer object and the sending itself.  Therefore, see
for possible options Mail::Transport::Send::new() and
Mail::Transport::Send::send().

Examples:

 $message->send;

is short (but little less flexibile) for

 my $mailer = Mail::Transport::SMTP->new(@smtpopts);
 $mailer->send($message, @sendopts);

See examples/send.pl in the distribution of Mail::Box.

=item B<size> 

Returns the size of the whole message in bytes.  This does assume that each
line ending is represented by one character (like UNIX, MacOS, and sometimes
Cygwin), and not two characters (like Windows and sometimes Cygwin).

If you write the message to file on a system which uses CR and LF to end a
single line (all Windows versions), the result in file will be nrLines() larger
than this method returns.

=item B<toplevel> 

Returns a reference to the main message, which will be the current
message if the message is not part of another message.

=item B<write> [FILEHANDLE]

Write the message to the FILE-HANDLE, which defaults to the selected
FILEHANDLE, with all surrounding information which is needed to put
it correctly in a folder file.

In most cases, the result of C<write> will be the same as with print().  The
main exception is for Mbox folder messages, which will get printed with
their leading 'From ' line and a trailing blank.  Each line of their body
which starts with 'From ' will have an E<gt> added in front.

=back

=head2 The Header

=over 4

=item B<head> [HEAD]

Return (optionally after setting) the HEAD of this message.
The head must be an (sub-)class of Mail::Message::Head.
When the head is added, status information is taken from it
and transformed into labels.  More labels can be added by the
LABELS hash.  They are added later.

Examples:

 $msg->head(Mail::Message::Head->new);  # set
 my $head = $msg->head;                 # get

=back

=head2 Header Shortcuts

=over 4

=item B<bcc> 

Returns the addresses which are specified on the C<Bcc> header line (or lines)
A list of Mail::Address objects is returned.
C<Bcc> stands for I<Blind Carbon Copy>: destinations of the message which are
not listed in the messages actually sent.  So, this field will be empty
for received messages, but may be present in messages you construct yourself.

=item B<cc> 

Returns the addresses which are specified on the C<Cc> header line (or lines)
A list of Mail::Address objects is returned.  C<Cc> stands for
I<Carbon Copy>; the people addressed on this line receive the message
informational, and are usually not expected to reply on its content.

=item B<date> 

Returns the last C<Date> header line as string.

Examples:

 my $date = $message->date;

=item B<destinations> 

Returns a list of Mail::Address objects which contains the combined info
of active C<To>, C<Cc>, and C<Bcc> addresses.  Doubles are removed.

=item B<from> 

Returns the address of the sender.  It is possible to have more than
one address specified in the C<From> field of the message. Therefore a
list of Mail::Address objects is returned, which usually has
length 1.

If you need one address of a sender, for instance to create a reply to,
then use sender().

Examples:

 my @from = $message->from;

=item B<get> FIELD

Returns the value which is stored in the header FIELD with the specified
name.  If the field has multiple appearances in the header, only the last
instance is returned.

The field name is case insensitive.  the I<unfolded body> of the field is
returned, see Mail::Message::Field::unfoldedBody().  If you need more complex
handing of fields, then call Mail::Message::Head::get() yourself.

Examples:

 print $msg->get('Content-Type'), "\n";

Is equivalent to:

 print $msg->head->get('Content-Type')->body, "\n";

=item B<guessTimestamp> 

Return an estimate on the time this message was sent.  The data is
derived from the header, where it can be derived from the C<date> and
C<received> lines.  For MBox-like folders you may get the date from
the from-line as well.

This method may return C<undef> if the header is not parsed or only
partially known.  If you require a time, then use the timestamp()
method, described below.

Examples:

 print "Receipt ", ($message->timestamp || 'unknown'), "\n";

=item B<nrLines> 

Returns the number of lines used for the whole message.

=item B<sender> 

Returns exactly one address, which is the originator of this message.
The returned Mail::Address object is taken from the C<Sender> header
field, unless that field does not exists, in which case the first
address from the C<From> field is taken.  If none of both provide
an address, C<undef> is returned.

Examples:

 my $sender = $message->sender;
 print "Reply to: ", $sender->format, "\n" if defined $sender;

=item B<subject> 

Returns the message's subject, or the empty string.

Examples:

 print $msg->subject;

=item B<timestamp> 

Get a timestamp, doesn't matter how much work it is.  If it is impossible
to get a time from the header-lines, the current time-of-living is taken.

=item B<to> 

Returns the addresses which are specified on the C<To> header line (or lines).
A list of Mail::Address objects is returned.  The people addressed
here are the targets of the content, and should read it contents
carefully.

Examples:

 my @to = $message->to;

=back

=head2 The Body

=over 4

=item B<body> [BODY]

Return the body of this message.  BE WARNED that this returns
you an object which may be encoded: use decoded() to get a body
with usable data.

With options, a new BODY is set for this message.  This is B<not>
for normal use unless you understand the consequences: you change
the message content without changing the message-ID.  The right
way to go is via

 $message = Mail::Message->buildFromBody($body);  # or
 $message = Mail::Message->build($body);          # or
 $message = $origmsg->forward(body => $body);

The BODY must be an (sub-)class of Mail::Message::Body.  In this case,
information from the specified body will be copied into the header.  The
body object will be encoded if needed, because messages written to file
or transmitted shall not contain binary data.  The converted body
is returned.

When BODY is C<undef>, the current message body will be dissected from
the message.  All relation will be cut.  The body is returned, and
can be connected to a different message.

Examples:

 my $body      = $msg->body;
 my @encoded   = $msg->body->lines;

 my $new       = Mail::Message::Body->new(mime_type => 'text/html');
 my $converted = $msg->body($new);

=item B<decoded> OPTIONS

Decodes the body of this message, and returns it as a body object.  If there
was no encoding, the body object as read from file is passed on, however,
some more work will be needed when a serious encoding is encountered.
The OPTIONS control how the conversion takes place.

 OPTION               DEFAULT
 keep                 <false>
 result_type          <type of body>

=over 4

=item B<keep> =E<gt> BOOLEAN

Controls whether the decoded result will be kept.  If not, the decoding
may be performed more than once.  However, it will consume extra
resources...

=item B<result_type> =E<gt> BODYTYPE

Specifies which kind of body should be used for the final result, and
eventual intermediate conversion stages.  It is not sure that this
will be the type of the body returned.  BODYTYPE extends Mail::Message::Body.

=back

Examples:

 $message->decoded->print(\*OUT);
 $message->decoded->print;

 my $dec = $message->body($message->decoded);
 my $dec = $message->decoded(keep => 1);   # same

=item B<encode> OPTIONS

Encode the message to a certain format.  Read the details in the
dedicated manual page Mail::Message::Body::Encode.  The OPTIONS which
can be specified here are those of the Mail::Message::Body::encode() method.

=item B<isMultipart> 

Check whether this message is a multipart message (has attachments).  To
find this out, we need at least the header of the message; there is no
need to read the body of the message to detect this.

=item B<parts> ['ALL'|'ACTIVE'|'DELETED'|'RECURSE'|FILTER]

Returns the I<parts> of this message. Usually, the term I<part> is used
with I<multipart> messages: messages which are encapsulated in the body
of a message.  To abstract this concept: this method will return you
all header-body combinations which are stored within this message.
Objects returned are Mail::Message's and Mail::Message::Part's.

The option default to 'ALL', which will return the message itself for
single-parts, the nested content of a message/rfc822 object, respectively
the parts of a multipart without recursion.  In case of 'RECURSE', the
parts of multiparts will be collected recursively.  This option cannot
be combined with the other options, which you may want: it that case
you have to test yourself.

'ACTIVE' and 'DELETED' check for the deleted flag on messages and
message parts.  The FILTER is a code reference, which is called for
each part of the messagei; each part as C<RECURSE> would return.

Examples:

 my @parts = $msg->parts;           # $msg not multipart: returns ($msg)
 my $parts = $msg->parts('ACTIVE'); # returns ($msg)

 $msg->delete;
 my @parts = $msg->parts;           # returns ($msg)
 my $parts = $msg->parts('ACTIVE'); # returns ()

=back

=head2 Access to the Message

=over 4

=item B<file> 

See Mail::Message::Construct::file()

=item B<lines> 

See Mail::Message::Construct::lines()

=item B<string> 

See Mail::Message::Construct::string()

=back

=head2 Labels

=over 4

=item B<label> LABEL [,VALUE [LABEL, VALUE] ]

Return the value of the LABEL, optionally after setting it to VALUE.  If
the VALUE is C<undef> then the label is removed.  You may specify a list
of LABEL-VALUE pairs at once.  In the latter case, the first VALUE is returned.

Labels are used to store knowledge about handling of the message within
the folder.  Flags about whether a message was read, replied to, or
(in some cases) scheduled for deletion.

Some labels are taken from the header's C<Status> and C<X-Status> lines,
however folder types like MH define a separate label file.

Examples:

 print $message->label('seen');
 if($message->label('seen')) {...};
 $message->label(seen => 1);

=item B<labels> 

Returns all known labels.  In SCALAR context, it returns the knowledge
as reference to a hash.  This is a reference to the original data, but
you shall *not* change that data directly: call C<label> for
changes!

In LIST context, you get a list of names which are defined.  Be warned
that they will not all evaluate to true, although most of them will.

=item B<labelsToStatus> 

When the labels were changes, there may be an effect for the
C<Status> and/or C<X-Status> header-lines.  Whether this update has
to take place depends on the type of folder.

=item B<statusToLabels> 

Update the labels according the status lines in the header.  Defined values
for the 'Status' field are C<R> (Read, label 'seen') and C<O> (label 'old').
Values for the 'X-Status' field are C<A> (Answered, label 'replied') and
C<F> (label 'flagged').

=back

=head2 Reading and Writing [internals]

=over 4

=item B<DESTROY> 

When a message is to accessible anymore by any user's reference, Perl
will call DESTROY for final clean-up.  In this case, the head and
body are released, and de-registered for the folder.  You shall not call
this yourself!

=item B<isDelayed> 

Check whether the message is delayed (not yet read from file).  Returns
true or false, dependent on the body type.

=item B<readBody> PARSER, HEAD [, BODYTYPE]

Read a body of a message.  The PARSER is the access to the folder's
file, and the HEAD is already read.  Information from the HEAD is used
to create expectations about the message's length, but also to determine
the mime-type and encodings of the body data.

The BODYTYPE determines which kind of body will be made and defaults to
the value specified by new(body_type).
BODYTYPE may be the name of a body class, or a reference
to a routine which returns the body's class when passed the HEAD as only
argument.

=item B<readFromParser> PARSER, [BODYTYPE]

Read one message from file.  The PARSER is opened on the file.  First
readHeader() is called, and the head is stored in the message.  Then
readBody() is called, to produce a body.  Also the body is added to
the message without decodings being done.

The optional BODYTYPE may be a body class or a reference to a code
which returns a body-class based on the header.

=item B<readHead> PARSER [,CLASS]

Read a head into an object of the specified CLASS.  The CLASS defaults to
the C<head_type> option specified at creation of the message (see new()).
The PARSER is the access to the folder's file.

=item B<storeBody> BODY

Where the body() method can be used to set and get a body, with all
the necessary checks, this method is bluntly adding the specified body
to the message.  No conversions, not checking.

=item B<takeMessageId> [STRING]

Take the message-id from the STRING, or create one when the C<undef>
is specified.  If not STRING nor C<undef> is given, the current header
of the message is requested for the value of the C<'Message-ID'> field.

Angles (if present) are removed from the id.

=back

=head2 Logging and Tracing

=over 4

=item B<defaultTrace> [LEVEL, [LEVEL]

See Mail::Reporter::defaultTrace()

=item B<errors> 

See Mail::Reporter::errors()

=item B<log> [LEVEL [,STRINGS]]

See Mail::Reporter::log()

=item B<printStructure> [FILEHANDLE][, INDENT]

See Mail::Message::Construct::printStructure()

=item B<report> [LEVEL]

See Mail::Reporter::report()

=item B<reportAll> [LEVEL]

See Mail::Reporter::reportAll()

=item B<trace> [LEVEL]

See Mail::Reporter::trace()

=item B<warnings> 

See Mail::Reporter::warnings()

=back

=head2 Other Methods

=over 4

=item B<AUTOLOAD> 

See Mail::Reporter::AUTOLOAD()

=item B<inGlobalDestruction> 

See Mail::Reporter::inGlobalDestruction()

=item B<logPriority> LEVEL

See Mail::Reporter::logPriority()

=item B<logSettings> 

See Mail::Reporter::logSettings()

=item B<notImplemented> 

See Mail::Reporter::notImplemented()

=back

=head1 SEE ALSO

A good start to read is Mail::Box-Overview.
More documentation and a mailinglist are available from the project's
website at L<http://perl.overmeer.net/mailbox/>.

=head1 AUTHOR

Written by Mark Overmeer (L<mark@overmeer.net|mailto:mark@overmeer.net>)
with the help of many.  See the ChangeLog for details.

=head1 VERSION

This code is beta, version 2.037.

Copyright (c) 2001-2003 by the authors. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
