dev@javamail.java.net

Re: Extensible fetch command

From: Bill Shannon <bill.shannon_at_oracle.com>
Date: Fri, 03 Aug 2012 17:28:43 -0700

I looked over your changes. There were a few issues, such as the need to be
able to build JavaMail with JDK 1.4, but otherwise it looked pretty reasonable.
I took your changes as inspiration to see what would be required to support the
subclassing approach. I've got something working but you were right, it was
somewhat more complicated than I expected. In the end, I think it will make for
a better approach since it will support adding extensions of other sorts as well.

Right now I've got support for fetching and searching X-GM-MSGID and X-GM-THRID
and searching for X-GM-RAW. I want to add support for X-GM-LABELS, which
shouldn't take long. XLIST support will likely take more time.

Although this is working, I think some further refactoring could make it easier,
and I want to spend some time thinking about that. I also need to think about
whether there's other Gmail-specific behavior that should be supported, beyond
what's described here
<https://developers.google.com/google-apps/gmail/imap_extensions>. When I'm
satisfied with what I've got, I'll push it out to the source workspace and
others can try it out.

Zsombor wrote on 07/24/12 16:42:
> Hi,
>
> Initially I though that sub-classing would work, but after looking through
> the code, it seems that a substantial amount of work is needed to convert the
> provider to an easily extensible one. There are a couple of long methods, even
> static ones - for example IMAPMessage.fetch(...) in this case, and the
> protocol parsing code are in more than one class - not only in IMAPProtocol,
> but in the FetchResponse.parse method too ( and this method is called from the
> constructor, which is a serious pain, when you try to subclass it).
> In the attached diff, I've tried to implement the 'extension-aware' IMAP
> handler. It uses the java.util.ServiceLoader to load 2 services. The
> FetchCommandBuilder, which responsibility is to handle one FetchProfile.Item :
> - FetchProfile.Item getResponsibleFor() - return this item
> - String getCommandFragment(FetchProfile) - return a non null string, if
> based on the FetchProfile the fetch command need a new parameter. For example :
> return (fp.contains(IMAPFolder.FetchProfileItem.SIZE)) ? "RFC822.SIZE" :
> null;
> - boolean needFetch(IMAPMessage) - return true, if this IMAPMessage doesn't
> contains the necessary information for the FetchProfile.Item
> The ItemBuilder is for creating com.sun.mail.imap.protocol.Item objects from
> the response. It has a name, and a build method to construct one.
>
> Obviously my code lacks any javadoc/documentation, but I hope it's a good
> start. What do you think ?
>
> Best Regards
> Zsombor
>
>
>
> On Mon, Jul 23, 2012 at 9:01 PM, Bill Shannon <bill.shannon_at_oracle.com
> <mailto:bill.shannon_at_oracle.com>> wrote:
>
> This has been on my list of things to think about for some time, but I
> haven't gotten to it yet.
>
> I think it should be possible to subclass the existing IMAP provider code
> to create a "gimap" provider, without the need to fork all of the JavaMail
> code. It may be necessary to enhance the base classes to make this work
> but that would definitely be worth considering.
>
> If you're interested in pursuing this yourself, please see the JavaMail
> Contributions page <http://kenai.com/projects/javamail/pages/Contributions>.
>
> One of the reasons I haven't pursued this myself yet is that I'm still
> trying to decide if this is the best approach. In some ways it would be
> easier to just build in the Gmail-specific features to the base IMAP
> classes. It's not as clean, but GMail is so widely used perhaps it's
> worth it?
>
> Yet another approach is similar to what I think you're suggesting. The
> base IMAP classes could be enhanced not with Gmail-specific support, but
> with more general extension points, which people could use to access
> Gmail-specific features. That might make it a bit more clumsy to access
> those Gmail features, but the extensibility might be useful for accessing
> product-specific features in other products as well.
>
> So I guess I see three options:
>
> 1. Build in Gmail-specific features
> 2. Make it easy to create a provider with Gmail-specific features by
> subclassing the existing IMAP provider
> 3. Make it easier to access product-specific features using the existing
> IMAP provider
>
> I was leaning towards #2, but I see the advantages of the others as well.
> I'd have to look into the details of the Gmail-specific features to see if
> #3 is feasible.
>
> Zsombor wrote on 7/22/12 11:17 AM:
>> Hi,
>>
>> Have you ever considered making the IMAP fetch command handling a bit
>> more extensible ? I mean, you probably aware, that gmail imap supports a
>> couple flags, which can be queried with a regular fetch command.
>> Unfortunately this doesn't work:
>>
>> FetchProfile fp = new FetchProfile();
>> fp.add(GMFetchProfileItem.MESSAGE_ID);
>> folder.fetch(messages, fp);
>>
>> where GMFetchProfileItem.MESSAGE_ID is a custom FetchProfile.Item.
>> It seems a common issue, because there is a javamail fork (
>> http://code.google.com/p/java-gmail-imap/ ) to address this shortcomings.
>> However, it's a google specific code, I can understand, that you don't
>> want to implement inside the core IMAP code. But I think, it is possible
>> to implement the necessary framework, so any user can write his own
>> plugin, so no forking will be needed for any custom flags. Will you
>> accept this kind of patches into javamail? Is it worth working on ?
>>
>> Thanks,
>> Zsombor
>>
>>
>>
>>
>
>