FileDocCategorySizeDatePackage
SearchSequence.javaAPI DocJavaMail 1.4.313735Tue Nov 17 10:38:10 GMT 2009com.sun.mail.imap.protocol

SearchSequence

public class SearchSequence extends Object
This class traverses a search-tree and generates the corresponding IMAP search sequence.
author
John Mani

Fields Summary
private static String[]
monthTable
Print an IMAP Date string, that is suitable for the Date SEARCH commands. The IMAP Date string is : date ::= date_day "-" date_month "-" date_year Note that this format does not contain the TimeZone
private static Calendar
cal
Constructors Summary
Methods Summary
private static com.sun.mail.iap.Argumentand(javax.mail.search.AndTerm term, java.lang.String charset)

	// Combine the sequences for both terms
	SearchTerm[] terms = term.getTerms();
	// Generate the search sequence for the first term
	Argument result = generateSequence(terms[0], charset);
	// Append other terms
	for (int i = 1; i < terms.length; i++)
	    result.append(generateSequence(terms[i], charset));
	return result;
    
private static com.sun.mail.iap.Argumentbody(javax.mail.search.BodyTerm term, java.lang.String charset)

	Argument result = new Argument();

	result.writeAtom("BODY");
	result.writeString(term.getPattern(), charset);
	return result;
    
private static com.sun.mail.iap.Argumentflag(javax.mail.search.FlagTerm term)

	boolean set = term.getTestSet();

	Argument result = new Argument();

	Flags flags = term.getFlags();
	Flags.Flag[] sf = flags.getSystemFlags();
	String[] uf = flags.getUserFlags();
	if (sf.length == 0 && uf.length == 0)
	    throw new SearchException("Invalid FlagTerm");

	for (int i = 0; i < sf.length; i++) {
	    if (sf[i] == Flags.Flag.DELETED)
		result.writeAtom(set ? "DELETED": "UNDELETED");
	    else if (sf[i] == Flags.Flag.ANSWERED)
		result.writeAtom(set ? "ANSWERED": "UNANSWERED");
	    else if (sf[i] == Flags.Flag.DRAFT)
		result.writeAtom(set ? "DRAFT": "UNDRAFT");
	    else if (sf[i] == Flags.Flag.FLAGGED)
		result.writeAtom(set ? "FLAGGED": "UNFLAGGED");
	    else if (sf[i] == Flags.Flag.RECENT)
		result.writeAtom(set ? "RECENT": "OLD");
	    else if (sf[i] == Flags.Flag.SEEN)
		result.writeAtom(set ? "SEEN": "UNSEEN");
	}

	for (int i = 0; i < uf.length; i++) {
	    result.writeAtom(set ? "KEYWORD" : "UNKEYWORD");
	    result.writeAtom(uf[i]);
	}
	
	return result;
    
private static com.sun.mail.iap.Argumentfrom(java.lang.String address, java.lang.String charset)

	Argument result = new Argument();
	result.writeAtom("FROM");
	result.writeString(address, charset);
	return result;
    
static com.sun.mail.iap.ArgumentgenerateSequence(javax.mail.search.SearchTerm term, java.lang.String charset)
Generate the IMAP search sequence for the given search expression.

	/* Call the appropriate handler depending on the type of
	 * the search-term ...
	 */
	if (term instanceof AndTerm) 		// AND
	    return and((AndTerm)term, charset);
	else if (term instanceof OrTerm) 	// OR
	    return or((OrTerm)term, charset);
	else if (term instanceof NotTerm) 	// NOT
	    return not((NotTerm)term, charset);
	else if (term instanceof HeaderTerm) 	// HEADER
	    return header((HeaderTerm)term, charset);
	else if (term instanceof FlagTerm) 	// FLAG
	    return flag((FlagTerm)term);
	else if (term instanceof FromTerm) {	// FROM
	    FromTerm fterm = (FromTerm)term;
	    return from(fterm.getAddress().toString(), charset);
	}
	else if (term instanceof FromStringTerm) { // FROM
	    FromStringTerm fterm = (FromStringTerm)term;
	    return from(fterm.getPattern(), charset);
	}
	else if (term instanceof RecipientTerm)	{ // RECIPIENT
	    RecipientTerm rterm = (RecipientTerm)term;
	    return recipient(rterm.getRecipientType(), 
			     rterm.getAddress().toString(),
			     charset);
	}
	else if (term instanceof RecipientStringTerm) { // RECIPIENT
	    RecipientStringTerm rterm = (RecipientStringTerm)term;
	    return recipient(rterm.getRecipientType(),
			     rterm.getPattern(),
			     charset);
	}
	else if (term instanceof SubjectTerm)	// SUBJECT
	    return subject((SubjectTerm)term, charset);
	else if (term instanceof BodyTerm)	// BODY
	    return body((BodyTerm)term, charset);
	else if (term instanceof SizeTerm)	// SIZE
	    return size((SizeTerm)term);
	else if (term instanceof SentDateTerm)	// SENTDATE
	    return sentdate((SentDateTerm)term);
	else if (term instanceof ReceivedDateTerm) // INTERNALDATE
	    return receiveddate((ReceivedDateTerm)term);
	else if (term instanceof MessageIDTerm) // MessageID
	    return messageid((MessageIDTerm)term, charset);
	else
	    throw new SearchException("Search too complex");
    
private static com.sun.mail.iap.Argumentheader(javax.mail.search.HeaderTerm term, java.lang.String charset)

	Argument result = new Argument();
	result.writeAtom("HEADER");
	result.writeString(term.getHeaderName());
	result.writeString(term.getPattern(), charset);
	return result;
    
static booleanisAscii(javax.mail.search.SearchTerm term)

	if (term instanceof AndTerm || term instanceof OrTerm) {
	    SearchTerm[] terms;
	    if (term instanceof AndTerm)
		terms = ((AndTerm)term).getTerms();
	    else
		terms = ((OrTerm)term).getTerms();

	    for (int i = 0; i < terms.length; i++)
		if (!isAscii(terms[i])) // outta here !
		    return false;
	} else if (term instanceof NotTerm)
	    return isAscii(((NotTerm)term).getTerm());
	else if (term instanceof StringTerm)
	    return isAscii(((StringTerm)term).getPattern());
	else if (term instanceof AddressTerm)
	    return isAscii(((AddressTerm)term).getAddress().toString());
	
	// Any other term returns true.
	return true;
    
private static booleanisAscii(java.lang.String s)

	int l = s.length();

	for (int i=0; i < l; i++) {
	    if ((int)s.charAt(i) > 0177) // non-ascii
		return false;
	}
	return true;
    
private static com.sun.mail.iap.Argumentmessageid(javax.mail.search.MessageIDTerm term, java.lang.String charset)

	Argument result = new Argument();
	result.writeAtom("HEADER");
	result.writeString("Message-ID");
	// XXX confirm that charset conversion ought to be done
	result.writeString(term.getPattern(), charset); 
	return result;
    
private static com.sun.mail.iap.Argumentnot(javax.mail.search.NotTerm term, java.lang.String charset)

	Argument result = new Argument();

	// Add the NOT search-key
	result.writeAtom("NOT");

	/* If this term is an AND expression, we need to enclose it
	 * within paranthesis. 
	 *
	 * AND expressions are either AndTerms or FlagTerms 
	 */
	SearchTerm nterm = term.getTerm();
	if (nterm instanceof AndTerm || nterm instanceof FlagTerm)
	    result.writeArgument(generateSequence(nterm, charset));
	else
	    result.append(generateSequence(nterm, charset));

	return result;
    
private static com.sun.mail.iap.Argumentor(javax.mail.search.OrTerm term, java.lang.String charset)

	SearchTerm[] terms = term.getTerms();

	/* The IMAP OR operator takes only two operands. So if
	 * we have more than 2 operands, group them into 2-operand
	 * OR Terms.
	 */
	if (terms.length > 2) {
	    SearchTerm t = terms[0];

	    // Include rest of the terms
	    for (int i = 1; i < terms.length; i++)
		t = new OrTerm(t, terms[i]);

	    term = (OrTerm)t; 	// set 'term' to the new jumbo OrTerm we
				// just created
	    terms = term.getTerms();
	}

	// 'term' now has only two operands
	Argument result = new Argument();

	// Add the OR search-key, if more than one term
	if (terms.length > 1)
	    result.writeAtom("OR");

	/* If this term is an AND expression, we need to enclose it
	 * within paranthesis.
	 *
	 * AND expressions are either AndTerms or FlagTerms 
	 */
	if (terms[0] instanceof AndTerm || terms[0] instanceof FlagTerm)
	    result.writeArgument(generateSequence(terms[0], charset));
	else
	    result.append(generateSequence(terms[0], charset));

	// Repeat the above for the second term, if there is one
	if (terms.length > 1) {
	    if (terms[1] instanceof AndTerm || terms[1] instanceof FlagTerm)
		result.writeArgument(generateSequence(terms[1], charset));
	    else
		result.append(generateSequence(terms[1], charset));
	}

	return result;
    
private static com.sun.mail.iap.Argumentreceiveddate(javax.mail.search.DateTerm term)

	Argument result = new Argument();
	String date = toIMAPDate(term.getDate());

	switch (term.getComparison()) {
	    case ComparisonTerm.GT:
		result.writeAtom("SINCE " + date);
		break;
	    case ComparisonTerm.EQ:
		result.writeAtom("ON " + date);
		break;
	    case ComparisonTerm.LT:
		result.writeAtom("BEFORE " + date);
		break;
	    case ComparisonTerm.GE:
		result.writeAtom("OR SINCE " + date + " ON " + date);
		break;
	    case ComparisonTerm.LE:
		result.writeAtom("OR BEFORE " + date + " ON " + date);
		break;
	    case ComparisonTerm.NE:
		result.writeAtom("NOT ON " + date);
		break;
	    default:
	    	throw new SearchException("Cannot handle Date Comparison");
	}

	return result;
    
private static com.sun.mail.iap.Argumentrecipient(javax.mail.Message$RecipientType type, java.lang.String address, java.lang.String charset)

	Argument result = new Argument();

	if (type == Message.RecipientType.TO)
	    result.writeAtom("TO");
	else if (type == Message.RecipientType.CC)
	    result.writeAtom("CC");
	else if (type == Message.RecipientType.BCC)
	    result.writeAtom("BCC");
	else
	    throw new SearchException("Illegal Recipient type");

	result.writeString(address, charset);
	return result;
    
private static com.sun.mail.iap.Argumentsentdate(javax.mail.search.DateTerm term)

	Argument result = new Argument();
	String date = toIMAPDate(term.getDate());

	switch (term.getComparison()) {
	    case ComparisonTerm.GT:
		result.writeAtom("SENTSINCE " + date);
		break;
	    case ComparisonTerm.EQ:
		result.writeAtom("SENTON " + date);
		break;
	    case ComparisonTerm.LT:
		result.writeAtom("SENTBEFORE " + date);
		break;
	    case ComparisonTerm.GE:
		result.writeAtom("OR SENTSINCE " + date + " SENTON " + date);
		break;
	    case ComparisonTerm.LE:
		result.writeAtom("OR SENTBEFORE " + date + " SENTON " + date);
		break;
	    case ComparisonTerm.NE:
		result.writeAtom("NOT SENTON " + date);
		break;
	    default:
	    	throw new SearchException("Cannot handle Date Comparison");
	}

	return result;
    
private static com.sun.mail.iap.Argumentsize(javax.mail.search.SizeTerm term)

	Argument result = new Argument();

	switch (term.getComparison()) {
	    case ComparisonTerm.GT:
		result.writeAtom("LARGER");
		break;
	    case ComparisonTerm.LT:
		result.writeAtom("SMALLER");
		break;
	    default:
		// GT and LT is all we get from IMAP for size
	    	throw new SearchException("Cannot handle Comparison");
	}

	result.writeNumber(term.getNumber());
	return result;
    
private static com.sun.mail.iap.Argumentsubject(javax.mail.search.SubjectTerm term, java.lang.String charset)

	Argument result = new Argument();
	
	result.writeAtom("SUBJECT");
	result.writeString(term.getPattern(), charset);
	return result;
    
private static synchronized java.lang.StringtoIMAPDate(java.util.Date date)


          
	StringBuffer s = new StringBuffer();

	/*
	 * Synchronized to coordinate access to shared Calendar object.
	 */
	synchronized (cal) {
	    cal.setTime(date);

	    s.append(cal.get(Calendar.DATE)).append("-");
	    s.append(monthTable[cal.get(Calendar.MONTH)]).append('-");
	    s.append(cal.get(Calendar.YEAR));
	}

	return s.toString();