How can you use BodyTerm to do a case sensitive search? The superclass' constructor that enables this isn't exposed.

allen petersen

There are two issues here. The first is the question of getting a SearchTerm whose match() method will do a case sensitive search. Unfortunately, as you've noticed, StringTerm's ignoreCase attribute is protected, and none of the subclasses that are provided in the JavaMail package make it available. To make matters more difficult, all of StringTerm's non-abstract subclasses are final, so you can't just subclass them and set the ignoreCase flag to false.

So that pretty much means that we have to write our own subclass of StringTerm. A trivial example, which doesn't even handle messages with attachments, would be

import javax.mail.*;
import javax.mail.search.*;

public class CaseSensitiveBodyTerm extends StringTerm {

  public CaseSensitiveBodyTerm(String pattern) {
    super(pattern, false);

  public boolean match(Message msg) {
    try {
      Object content = msg.getContent();
      if (content instanceof String) {
        return super.match((String)content);
      } else {
        return false;
    } catch (Exception e) {
      return false;

Now, there is a second problem that you may run into. If you're using IMAP, the IMAP provider will use the IMAP SEARCH functionality to do a Folder.search() call for you. This is much more efficient than downloading every message in your folder to your client and then doing the search on the local messages. Unfortunatley, since the IMAP SEARCH command is defined to be case insensitive, that latter method is exactly what the search call will fall back to if you use this custom case sensitive SearchTerm. For large folders, this search could take upwards on forever. In cases like that, you're probably better off making a special case that does the case insensitive search on the server, and then filters the responses by the case sensitive search.