Robert Burrell Donkin ha scritto:
On Tue, Sep 2, 2008 at 9:53 AM, Stefano Bagnara <[EMAIL PROTECTED]> wrote:
IN past we discussed about what IoC style we prefer and SDI was the
"winner":
http://issues.apache.org/jira/browse/JAMES-494

Here you can find the biggest poll we've ever had ;-)
http://markmail.org/message/rfagbuq6t3au7uia
"G" questions was about dependency injection.

i did remark that setting injection is more popular but i don't intend
to set a president, just take one more step forward. it may give some
pointers towards more general solutions

I agree. I just wanted to share with you what we discussed in past.

Removing the default constructor will also make my new mailet report maven
module to fail obtaining the getMailetInfo/getMatcherInfo answer. It have to
get a newInstance in order to invoke that method.

Not a big deal, and if you go with CDI it will anyway be easy to refactor to
SDI in any moment.

setter injection would work best with annotations or interfaces

paired interfaces could be retrofitted easily. for example

interface Mailbox

interface MailboxAware
{
   public void setMailbox(Mailbox mailbox)
}

I call this "enabling interfaces", and I love them.

2. no conventions need to be established or explained. as a temporary
measure, it's easy to check and inject a limited number of SPIs
through reflection.

i would prefer to avoid major changes before moving IMAP out
We have a "store" method in MailetContext and we deprecated it because it
was not clear how to proceed and we simply discouraged it's usage to feel
more free to change it later :-)

IMHO MailetContext suffers from doing both too much and too little

I agree.

I don't understand if you are proposing something to be added to the
mailet
specification
ATM AIUI the mailet specification is silent on assembly and service
acquisition. one advantage of this strategy is that it's possible to
alter these characteristics without altering the mailet specification.
True and False... there was not support anything using services will not
work on current containers. So let's say "there's no way to be backward
compatible, so we can do whatever we want" ;-)

Every existing container will fail to load a mailet without a default
constructor.

i'm not sure how you know that's true

I know of some mailet containers: James, MailCatcher. All of them use class.newInstance() to load a mailet.

If you know of an existing *mailet* container not doing so and leveraging more flexible containers to instantiate mailets I would be happy to know this.

[...]
When I refactored this in my mind there was the idea to bring as many
components to a top level. The idea is that StateAwareProcessorList could be
a component itself and the SpoolManager could simply depend on a
MailProcessor component.

This should be easy to do now. I didn't do that before simply because when I
worked on this everyone was worried about backward compatibility, so no
change was allowed to break config.xml and db content compatibility. There
are many hacks in the code to deal with this.

i'm not sure why factoring out the processor would break configuration
compatibility

Because of the way "Configuration" object works in Phoenix.
The SpoolProcessor contains the Configuration for StateAwareProcessorList so if you move StateAwareProcessorList to an external component phoenix will initialize it before the spoolmanager and there is no way to get the configuration from SpoolManager. You should let phoenix instantiate the StateAwareProcessorList "unconfigured" and then manually configure it when it will "service" the SpoolManager. Indeed an hack.

If you instead don't like of config.xml compatibility then you simply take the xml tree for the StateAwareProcessorList and move it outside from the <spoolmanager> block.

or simply you are proposing to change the way james specific
mailets are written so to not require avalon knowledge to the james
specific
mailets.
IMHO JAMES specific mailets are an anti-pattern. we need to work
towards decoupling minimal SPIs for mailets from the large APIs used
internally by JAMES. i prefer to think about mailet loaders and
processor assemblers indepedently. avalon is not a good match for this
problem. more modern IoC containers like pico or spring as *much*
better.
I agree that james specific mailets are antipattern.
To make them generic you have to define services at the mailet level.
And make the services generic.

To change the service lookup method without publicizing the services does
not make the mailets portable to other services.
If a Mailet depends on SpoolRepository interface we can remove avalon and
the service manager by using simple CDI/SDI, but in the end the mailet will
be only usable where SpoolRepository implementations are available.
SpoolRepository is james specific.

MailboxSPI is james specific until we make it part of a generic API
supported by compliant containers.
I don't understand what is your idea about this? Do you want to make an
mailet-spi package with optional services to be supported by advanced
containers?

yep

i strongly dislike the use of the magic avalon service attribute. IMHO
if a mailet is coupled to avalon then it should implement the standard
servicable interface. the container could then recognize this and
configure the mailet appropriately.
I agree that the context and the service lookup are a bad idea for mailets.
IMHO this is a necessary change, but this alone won't change the fact that
mailets are james specific.

In http://issues.apache.org/jira/browse/JAMES-494 you can see the easiest
approach is to add setters for dependencies and make the "service" method
lookup the services and set them via setters. This way the avalon container
will keep working while non avalon containers can simply use setters.

i'm not sure i agree with this being the easiest approach. there are
known issues when trying to implement good setter injection frameworks
and conventions would have to be established for setter names unless
annotations are used.

the simplest approach would be to use constructor injection and
exclude optional dependencies

IMO the best approach for setter injection would be to create an
alternative spring processor loader

i'd like to be able to deploy a self contained jar'd mail application
eg (sketching somewhat):

META-INF/org/apache/james/list-processor.xml

<procesor loader='org.apache.james.mailet.container.Spring'>
   <mailet name='ListManager'>
....
   </mailet>
</processor>

META-INF/org/apache/james/spring-mailets.xml

<beans>
 <bean id='ListManager' class=...>
....
 </bean>
</beans>

Currently it is not the Processor loading the mailets but the MailetLoader and MatcherLoader services. YOu have to create new implementations of that services.

In StateAwareProcessorList each processor can optionally declare an alternative implementation via the "class" attribute, defaulting to org.apache.james.transport.LinearProcessor.

As you can see the LinearProcessor uses the MailetLoader and MatcherLoader services to load the mailets given their name and their configuration.

Do you want to implementa LinearProcessor that simply ignore the MailetLoader/MatcherLoader service and use it's own loading mechanism?

I'm not sure I like this, but it can be a PoC.

Another doubt is about the use of "String url": can you give more details
on
the allowed values for url and the way it works (a couple of examples
would
suffice, I guess)?
i've been thinking for a long while that there might be a lot to gain
in flexibility by moving towards APIs using URIs

but it's still hazy...

Last point, and the least important, I don't like the SPI postfix.
The same interface could be used by SMTPServer/Fetchmail to store
messages
to the spool. In fact a spool repository could expose this interface
(ignoring the url) or we could expose it via the Store by looking up the
appropriate spool repository and storing the message to it.
i have been thinking about that direction

for example, POSTing to "mailto://[EMAIL PROTECTED]" is an elegant and
concise way to express the idea of forwarding a mail. this can be used
for delivery as well. for example "mailet://[EMAIL PROTECTED]".

the advantage of using URLs is that it's easier to present interfaces
which work ok for a wider variety of protocols. for example POSTing to
"imap://[EMAIL PROTECTED]/INBOX" could be distringuished from
"james://[EMAIL PROTECTED]/INBOX" and "mailbox://[EMAIL PROTECTED]/INBOX".
might be possible to do some interesting stuff this way.
I like this stuff very much. I discussed a similar thing in past. I named it
"destinations":
http://markmail.org/message/xkcttgyqmfwpieew

In my 2005 idea "destinations" was particular email addresses because email
address is more "mail" oriented than url, but mail is moving to different
transport and everyone probably better understand urls than email addresses.

But I think it would be a very interesting paradigm to use urls for anything
from local spool management, to remote delivery to forward and anything
else.

The issue I see here is that we should understand how they works before
starting to add interfaces using this urls.

the sieve mailet is still experiement: it's a good opportunity just to
give it a go and take the chance to live with it for a while

As long as it is clear that this can be dropped at any time and it is only an experiment, and that there is no agreement yet that it is the correct solution, I'm fine with it. Go ahead.

Stefano

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

Reply via email to