pjs/grendel/storage/addressparser/RFC822MailboxList.java

318 строки
7.8 KiB
Java

/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Grendel mail/news client.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1997
* Netscape Communications Corporation. All Rights Reserved.
*
* Created: Eric Bina <ebina@netscape.com>, 30 Oct 1997.
*/
package grendel.storage.addressparser;
import java.io.*;
import java.util.*;
/**
* A subclass of <b>RFC822AddressList</b>. Its purpose is to create
* a more human readable list of all the addresses of this address list.
* To that end it flattens RFC822 groups in place into mailbox lists.
* It also attempts to save those occasions when name information
* is stored in a comment with an addr-spec instead of being put into
* the more complete form of (phrase route-addr).
*
* @see RFC822AddressList
* @author Eric Bina
*/
public class RFC822MailboxList extends RFC822AddressList
{
private Vector mailbox_list;
private RFC822Mailbox mailboxes[];
public RFC822MailboxList(String str)
{
super(str);
if (this.parser != null)
{
createMailboxList();
createMailboxArray();
}
}
/**
* @return An array of <b>RFC822Mailbox</b> objects.
* Methods on the object are used to get strings
* to display.
*
* @see RFC822Mailbox
*/
public RFC822Mailbox[] getMailboxArray()
{
return(this.mailboxes);
}
/*
* Size of the mailbox list.
*/
public int mailboxCount()
{
if (this.mailbox_list == null)
{
return(0);
}
else
{
return(this.mailbox_list.size());
}
}
/***********************
***********************
** PRIVATE METHODS **
***********************
***********************/
/*
* Make an array of standalone RFC822Mailbox objects
* which contain all the needed string data.
*/
private void createMailboxArray()
{
int cnt = this.mailbox_list.size();
this.mailboxes = new RFC822Mailbox[cnt];
for (int i=0; i<cnt; i++)
{
MailboxToken mailbox;
Vector parser_tokens = this.parser.getTokenList();
mailbox = (MailboxToken)this.mailbox_list.elementAt(i);
this.mailboxes[i] = new RFC822Mailbox(mailbox.getName(parser_tokens),
mailbox.getAddress(parser_tokens));
}
}
/*
* Convert the list of MailAddressTokens to a list
* of MailboxTokens. A GroupToken can become
* zero or more MailboxTokens.
*/
private void createMailboxList()
{
MailAddressToken address;
Vector address_list;
int list_size;
if (this.mailbox_list != null)
{
return;
}
this.mailbox_list = new Vector();
address_list = this.parser.getAddressList();
list_size = address_list.size();
for (int a=0; a < list_size; a++)
{
MailboxToken mailbox;
Vector group_mboxes;
int mbox_cnt;
address = (MailAddressToken)address_list.elementAt(a);
mailbox = address.getMailbox();
if (mailbox != null)
{
this.mailbox_list.addElement((Object)mailbox);
continue;
}
/*
* If here we have a group.
*/
group_mboxes = address.getGroup().getMailboxList();
if (group_mboxes.isEmpty() == true)
{
continue;
}
mbox_cnt = group_mboxes.size();
for (int m=0; m < mbox_cnt; m++)
{
this.mailbox_list.addElement(
group_mboxes.elementAt(m));
}
}
/*
* Pull all the comments associated with each mailbox
* out of the original token list because we may
* need to use them to make a name if none was
* provided.
*/
collectMailboxComments();
}
/*
* Pull all comments from the original token list from the
* start to the end of the mailbox and save them to later construct
* a name for this mailbox if needed.
*/
private void collectMailboxComments()
{
int list_size;
int start, end;
int all_indx, sub_indx;
if (this.mailbox_list == null)
{
return;
}
all_indx = 0;
sub_indx = 0;
list_size = this.mailbox_list.size();
for (int m=0; m < list_size; m++)
{
MailboxToken mailbox;
int indx;
mailbox = (MailboxToken)this.mailbox_list.elementAt(m);
/*
* Get all comments up top the last token of
* the mailbox.
*/
indx = addMailboxComments(mailbox, all_indx, sub_indx,
mailbox.getTokenEnd());
all_indx = indx;
sub_indx = mailbox.getTokenEnd();
/*
* If there are comments before the separating comma
* or semi-colon (from a group) get those.
*/
if (isMailboxSpacer(sub_indx + 1))
{
all_indx = addMailboxComments(mailbox, all_indx, sub_indx, (sub_indx + 1));
sub_indx++;
}
/*
* If there is no spacer, and there are currently no
* comments for this mailbox, take the trailing
* comment if it exists.
*/
else if ((mailbox.noComments())&&(isComment(all_indx + 1)))
{
RFC822Token token = (RFC822Token)this.all_tokens.elementAt(all_indx + 1);
mailbox.addComment(token);
all_indx = all_indx + 2;
sub_indx++;
}
/*
* Catch trailing comments on last mailbox
*/
if (m == (list_size - 1))
{
while (isComment(all_indx + 1) == true)
{
RFC822Token token = (RFC822Token)this.all_tokens.elementAt(all_indx + 1);
mailbox.addComment(token);
all_indx++;
}
}
}
}
/*
* Find any comments in the original token list that were
* stripped from between the passed start and end of
* the parser's token sublist. Add any such comments
* to the passed mailbox. Return the position in the original
* token list that corresponds to the passed end in the
* token sublist.
*/
private int addMailboxComments(MailboxToken mailbox, int all_indx,
int sub_start, int sub_end)
{
while (sub_start <= sub_end)
{
if (isComment(all_indx) == true)
{
RFC822Token token = (RFC822Token)this.all_tokens.elementAt(all_indx);
mailbox.addComment(token);
all_indx++;
}
else
{
all_indx++;
sub_start++;
}
}
return(all_indx - 1);
}
/*
* Mailboxes are always in comma separated lists, except for the
* last mailbox of a group that is terminated by a ';'.
* Check if the passed token in the token sublist could
* be a mailbox separator.
*/
private boolean isMailboxSpacer(int indx)
{
RFC822Token token;
Vector parser_tokens;
parser_tokens = this.parser.getTokenList();
if (indx >= parser_tokens.size())
{
return(false);
}
token = (RFC822Token)parser_tokens.elementAt(indx);
if ((token.isSpecialChar(',') == true)||(token.isSpecialChar(';') == true))
{
return(true);
}
return(false);
}
/*
* Is the index passed into the main token list a comment token?
*/
private boolean isComment(int indx)
{
RFC822Token token;
if (indx >= this.all_tokens.size())
{
return(false);
}
token = (RFC822Token)this.all_tokens.elementAt(indx);
if (token.getType() == RFC822Token.COMMENT)
{
return(true);
}
return(false);
}
}