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

Attachment: NewRedirectAndSons.zip
Description: Macintosh archive

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to