On Wed, 2013-05-15 at 18:24 +0200, Stefano Bagnara wrote: > 2013/5/15 Oleg Kalnichevski <[email protected]>: > > (1) Do nothing. While the present DOM API is not fancy and fluid and all > > it works. > > (2) Make DOM elements (almost) immutable but keep the existing > > Disposable model at the expense of having a few fringe cases when the > > same body part instance can end up referenced by multiple Message > > objects. Disposal of one message will inadvertently render other > > instances' state invalid. > > In order to better judge the best option I would have to understand > what immutability bring us. > I don't care at all that a single element could be shared between > messages or that a single message (or part of it) could be manipulated > concurrently by multiple threads. > On the other side I care of clean/simple API. >
There is more to immutability than just thread safety. Immutable objects are always guaranteed to be in a consistent state. Always. This is actually quite nice once you come to depend on it. This is currently a trend and trends may pass but there is a common belief that builder fluent pattern suits well for initialization of complex objects with many various dependencies. JAX-RS API could be a good example of that. > Can you provide a snippet of code for the current API that you don't > like and how you expect it to be after an immutable/almostimmutable > refactoring? > It is not the best example but something that actually works already before refactoring https://svn.apache.org/repos/asf/james/mime4j/tags/apache-mime4j-project-0.7/dom/src/main/java/org/apache/james/mime4j/message/BasicBodyFactory.java after refactoring https://svn.apache.org/repos/asf/james/mime4j/trunk/dom/src/main/java/org/apache/james/mime4j/message/BasicBodyFactory.java > > (3) Reconsider resource management concept. One possibility would be to > > move responsibility for resource disposal from DOM elements to Storage > > manager. > > If I understand it, this would always expose the Storage manager to > the DOM user. > > I find this is a frequent DOM use case: > > try { > message = messageBuilder.parseMessage(new EOLConvertingInputStream(is)); > } catch (...) { > ... > } finally { > message.dispose(); > } > Absolutely not. On the contrary those users who do not need special storage would no longer have to dispose of Message objects. > This code currently uses the dom package and doesn't even know a > storage package exists. That's the whole point. We have a situation when a requirement relevant for a fraction of user population imposes design decisions that impact ALL users. > You could pass a different messageBuilder (using an advanced storage > technique) to this code and it should works the same way... are you > suggesting that every dom users should be forced to deal with a > storage manager to tell when it's done working with a message? Can you > make an example? > That's how it could look (warning: it is pseudo-code) --- StorageManager sm = new SomeStorageManager(); try { Message m1 = new MessageBuilder() .setStorageManager(sm) .parse(stream) .build(); Message m2 = new MessageBuilder() .setStorageManager(sm) .parse(stream) .addThis() .changeThat(). .build(); Message m3 = new MessageBuilder() .setStorageManager(sm) .copy(m2) .addMore() .build(); // force disposal of a message, if required sm.dispose(m2); // Message m3 should still remain in a consistent state } finally { // Disposes of resources held by Message m1 and m3 sm.close(); } --- Oleg
