This is something I would like to see as well. One way to have you cake and eat
it too would be to define implementations as mutable, but have them implement
immutable interfaces:
public interface ImmutableMessage
{
// getters
// other non-state-changing methods (clone(), equals(), hashcode(), et
all; optional)
}
public interface MutableMessage extends ImmutableMessage
{
// setters only (getters implied via inheritance)
// any state-changing methods (?)
}
public class MessageImpl implements MutableMessage
{
// getters and setters
}
The MessageBuilder would return MutableMessage to the mime4j client, which can
in turn pass this along to any downstream code in the application as a
(threadsafe) ImmutableMessage, since MutableMessage extends ImmutableMessage.
This would, of course, require that any properties returned from the getters in
ImmutableMessage be either defensively copied, or mutable themselves, and today
we have a getter that returns java.util.Date, which is mutable, and not
defensively copied. On the other hand, since message implementations are
mutable, message construction performance and "intuitiveness" shouldn't be
affected -- this solution just provides an optional immutable "view" into the
existing mutable data structures via a simple (safe) cast. Additionally, this
solution doesn't have to be implemented in a way that breaks the existing API
(although the API probably shouldn't expose java.util.Date, but that's a
separate issue).
Another solution would be to define a completely separate immutable class
heirarchy that "wraps" the existing mutable heirachy, but that is far less
elegant. Applications can do this today with no effort on mime4j's part.
I think the cleanest overall option, is to simply change the API to be
completely immutable, and rewrite all message creation code to work with an
immutable API, but I think it's too late for that at this point, and possibly
not a great idea to begin with.
Just my $0.02.
-Rob L
-----Original Message-----
From: Oleg Kalnichevski [mailto:[email protected]]
Sent: Tuesday, September 04, 2012 4:47 AM
To: [email protected]
Subject: Re: [DISCUSSION] make most of mime4j immutable
On Mon, 2012-09-03 at 09:39 +0200, Stefano Bagnara wrote:
> At the moment the dom interfaces are also used to alter/create
> messages using mime4j so they cannot be made immutable.
>
I think this can also be done with the builder pattern by making builder accept
an existing message or an InputStream content as an input. My concern here
would be about efficiency. It would probably be unwise to end up with an
implementation that causes a significant amount of
intermediate copying just to have one extra field added or modified.
> I don't see big advantages in making it thread safe as I don't see
> many use case where a single message is parsed into a dom and read by
> multiple threads concurrently: can you provide an use case?
>
One must be mad to modify mime messages concurrently by multiple threads.
Still, the idea of making DOM level interfaces immutable is
worth pursuing, even at the price of API changes.
+1 to the overall idea.
Oleg
> On the other side immutability could bring us some performance, but
> this doesn't require an API change: if this is the goal then we could
> provide an immutable dom implementation and let a specific builder to
> build the dom using immutable classes (that will throw exceptions if
> some setter is called).
>
> Stefano
>
> 2012/9/2 Ioan Eugen Stan <[email protected]>:
> > Hello,
> >
> > After looking around in mime4j I noticed that most of the API
> > interfaces from mime4j-dom provide getters and are mutable. This
> > means that implementations are also not thread safe.
> >
> > I propose we move to an Immutable API implementation with nice
> > builders. This will make things thread safe and make life easier for
> > our users.
> >
> > This will most likely mean a change in the API.
> >
> > I think this is worth it, as we may have less bugs in our
> > (multi-threaded) code. What do you think?
> >
> > Cheers,
> >
> > --
> > Ioan Eugen Stan / CTO / http://axemblr.com