1d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen/**************************************************************** 2d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Licensed to the Apache Software Foundation (ASF) under one * 3d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * or more contributor license agreements. See the NOTICE file * 4d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * distributed with this work for additional information * 5d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * regarding copyright ownership. The ASF licenses this file * 6d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * to you under the Apache License, Version 2.0 (the * 7d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * "License"); you may not use this file except in compliance * 8d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * with the License. You may obtain a copy of the License at * 9d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * * 10d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * http://www.apache.org/licenses/LICENSE-2.0 * 11d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * * 12d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Unless required by applicable law or agreed to in writing, * 13d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * software distributed under the License is distributed on an * 14d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * KIND, either express or implied. See the License for the * 16d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * specific language governing permissions and limitations * 17d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * under the License. * 18d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen ****************************************************************/ 19d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 20d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenpackage org.apache.james.mime4j.field.address; 21d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 22d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport org.apache.james.mime4j.field.address.parser.AddressListParser; 23d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport org.apache.james.mime4j.field.address.parser.ParseException; 24d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 25d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport java.io.StringReader; 26d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenimport java.util.ArrayList; 27d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 28d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen/** 29d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * An immutable, random-access list of Address objects. 30d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 31d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 32d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 33d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chenpublic class AddressList { 34d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 35d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen private ArrayList<Address> addresses; 36d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 37d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 38d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param addresses An ArrayList that contains only Address objects. 39d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * @param dontCopy true iff it is not possible for the addresses ArrayList to be modified by someone else. 40d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 41d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public AddressList(ArrayList<Address> addresses, boolean dontCopy) { 42d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (addresses != null) 43d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen this.addresses = (dontCopy ? addresses : new ArrayList<Address>(addresses)); 44d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen else 45d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen this.addresses = new ArrayList<Address>(0); 46d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 47d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 48d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 49d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The number of elements in this list. 50d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 51d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public int size() { 52d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return addresses.size(); 53d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 54d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 55d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 56d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Gets an address. 57d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 58d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public Address get(int index) { 59d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (0 > index || size() <= index) 60d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen throw new IndexOutOfBoundsException(); 61d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return addresses.get(index); 62d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 63d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 64d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 65d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Returns a flat list of all mailboxes represented 66d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * in this address list. Use this if you don't care 67d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * about grouping. 68d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 69d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public MailboxList flatten() { 70d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen // in the common case, all addresses are mailboxes 71d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen boolean groupDetected = false; 72d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen for (int i = 0; i < size(); i++) { 73d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (!(get(i) instanceof Mailbox)) { 74d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen groupDetected = true; 75d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen break; 76d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 77d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 78d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 79d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (!groupDetected) 80d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return new MailboxList(addresses, true); 81d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 82d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen ArrayList<Address> results = new ArrayList<Address>(); 83d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen for (int i = 0; i < size(); i++) { 84d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen Address addr = get(i); 85d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen addr.addMailboxesTo(results); 86d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 87d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 88d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen // copy-on-construct this time, because subclasses 89d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen // could have held onto a reference to the results 90d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return new MailboxList(results, false); 91d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 92d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 93d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 94d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Dumps a representation of this address list to 95d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * stdout, for debugging purposes. 96d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 97d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public void print() { 98d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen for (int i = 0; i < size(); i++) { 99d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen Address addr = get(i); 100d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen System.out.println(addr.toString()); 101d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 102d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 103d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 104d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 105d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Parse the address list string, such as the value 106d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * of a From, To, Cc, Bcc, Sender, or Reply-To 107d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * header. 108d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * 109d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * The string MUST be unfolded already. 110d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 111d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public static AddressList parse(String rawAddressList) throws ParseException { 112d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen AddressListParser parser = new AddressListParser(new StringReader(rawAddressList)); 113d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return Builder.getInstance().buildAddressList(parser.parse()); 114d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 115d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen 116d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen /** 117d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen * Test console. 118d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen */ 119d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen public static void main(String[] args) throws Exception { 120d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); 121d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen while (true) { 122d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen try { 123d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen System.out.print("> "); 124d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen String line = reader.readLine(); 125d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen if (line.length() == 0 || line.toLowerCase().equals("exit") || line.toLowerCase().equals("quit")) { 126d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen System.out.println("Goodbye."); 127d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen return; 128d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 129d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen AddressList list = parse(line); 130d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen list.print(); 131d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 132d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen catch(Exception e) { 133d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen e.printStackTrace(); 134d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen Thread.sleep(300); 135d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 136d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 137d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen } 138d186a38568ddec7efcba054ccc2fe8ed9b8945fcNancy Chen} 139