Noel, I'm attaching to this message the code of the new Redirect and NotifySender mailets; the others (NotifyPostmaster, Forward and the new Bounce) will follow in the next days, and should be straightforward.
I have tested thoroughly (at least I put my best efforts), and they seem to work quite
well.
They should also be well (?) documented using javadoc: it is my intention though to
add a special "notes for implementors" section with guidelines on how to extend
Redirect and override its protected methods.
A few notes here:
---------------------
1) I have followed (at least I hope so) the guidelines discussed among us (all the
getX and setX stuff).
1.1 The service(Mail) code begins creating a new Mail object (called all around
"newMail") calling duplicate(getMailetContext().getId()) on the original Mail object,
called all around "originalMail".
1.2 Then, based on the inline type being UNALTERED or not, and based on passThrough
being false or true, the newMail object will either share the MimeMessage with
originalMail, or embed a copy of it, or embed a brand new MimeMessage to build. The
detailed code here is taken (and modified) from the NotifySender code patched by you
for James version 2.1.3.
1.3 After that, the various setX methods are called to modify newMail using the
outcome of getX(originalMail) .
1.4 Then a newMail.getMessage().saveChanges() is issued and afterwards, if the inline
type is UNALTERED, the message id of newMail is reset to the message id of the
originalMail, otherwise it gets a new message id.
1.5 Finally, as newMail is ready, a getMailetContext().sendMail(newMail) is issued,
and passThrough processing is done. Note here that, as sendMail(Mail) is not defined
in the MailetContext interface, although is implemented in the James class, I had to
modify MailetContext: I didn't like to code ((James)
getMailetContext()).sendMail(newMail), and supposed that it was simply forgotten. Also
the getId() method needed above (see 1.1) was missing in MailetContext, so I added it
too. If it is not OK let me know what to do.
2) A slight departure from the agreed "protocol": some setX methods (setSender when
sender is null, setSubjectPrefix and the new setIsReply) need to access also some
other information from originalMail (it is safer than getting them from newMail,
because the order could matter), so I had to change setX(Mail, Tx) to setX(Mail, Tx,
Mail), the first Mail being the newMail object to modify, and the second one being
originalMail to consult if and when needed. So the calls are:
setX(newMail, getX(originalMail), originalMail);
As I foresee such need for other subclasses, I used this third parameter in all setX
methods. It simply doesn't hurt.
3) To define IDENTITY constant MailAddress-es, that I use to "late bind" the "magic"
values, I inserted them in the *MailAddress class* as follows:
public static final MailAddress SENDER = new MailAddress();
...
and are referenceable as MailAddress.SENDER, MailAddress.UNALTERED etc. My choice to
put such constants in the MailAddress class was to make them available for future
usage, and to overcome a "throws ParseException" declared in the various constructors
of MailAddress. To do that I defined a new private constructor MailAddress() (see the
code). If you don't like this solution let me know.
4) I carefully wrote Redirect in order to not (hopefully) break any subclass that may
have been already written; at the same time I adopted a rule of behaviour that, when
followed by implementors of new subclasses (as I did for NotifySender), would allow to
set always the static parameter to true, and always return isStatic() as true, and
having the performance advantages of static but with the flexibility of dynamic.
4.1 As discussed in previous emails in this list, the rule is to separate the roles of
getX() and getX(Mail) *exactly* based on the first being static and the second being
dynamic. So, following it, I can set static always to true, even working with "magic"
values both in Redirect and in new subclasses (see new NotifySender). Any existing
subclass of Redirect, if has used a getX() dynamically, just needs, as before, to set
static to false, and will continue to work as before.
5) I also carefully wrote Redirect in order to (i) continue to behave as before (even
looking at the text generated) when defined in an existing config.xml, so it is not
breaking existing usages, and to (ii) allow the same for existing mailets that will
become a subclass of it, like NotifySender.
5.1 At the same time I've tried to have things done in order to allow Redirect to be
anytime a substitution of any of it subclasses, at least logically although not
generating the same text in the messages, just by coding appropriately its init
parameters in config.xml. To do that I added, and documented, some new parameters and
"magic" values (and related getX() methods) that will default to the old behaviour:
<returnPath> and <isReply>. I added also new values to existing parameters, like
<to>unaltered</to> asked by Hontvari Jozsef. I think that this goal should always be
pursued, and I will add new parameters etc. to Redirect if the need arises while
coding the new subclasses.
Nothing else comes to my mind now.
-------------------
As said, I tested the code and I think it is OK, but obviously more people should do
it before releasing.
I'm also expecting comments from you and the others, that hopefully will not force me
to recode too much :-)
In the meantime I will code the other subclasses, hoping to have them ready in a few
days. I need though ASAP an OK from you and others to proceed.
Thanks
Vincenzo
NewRedirectAndSons.zip
Description: Macintosh archive
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
