001    /*
002     * Copyright 2010 the original author or authors.
003     * 
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package com.hs.mail.imap.processor.fetch;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.james.mime4j.field.address.AddressList;
024    import org.apache.james.mime4j.field.address.DomainList;
025    import org.apache.james.mime4j.field.address.Group;
026    import org.apache.james.mime4j.field.address.Mailbox;
027    import org.apache.james.mime4j.field.address.MailboxList;
028    import org.apache.james.mime4j.field.address.parser.ParseException;
029    import org.apache.log4j.Logger;
030    import org.springframework.util.CollectionUtils;
031    
032    import com.hs.mail.imap.ImapConstants;
033    
034    /**
035     * 
036     * @author Won Chul Doh
037     * @since Mar 8, 2010
038     *
039     */
040    public class EnvelopeBuilder {
041            
042            private static Logger logger = Logger.getLogger(EnvelopeBuilder.class);
043            
044            public static final String[] WANTED_FIELDS = new String[] {
045                            ImapConstants.RFC822_DATE, ImapConstants.RFC822_SUBJECT,
046                            ImapConstants.RFC822_FROM, ImapConstants.RFC822_SENDER,
047                            ImapConstants.RFC822_REPLY_TO, ImapConstants.RFC822_TO,
048                            ImapConstants.RFC822_CC, ImapConstants.RFC822_BCC,
049                            ImapConstants.RFC822_IN_REPLY_TO, ImapConstants.RFC822_MESSAGE_ID };
050            
051            public Envelope build(Map<String, String> header) {
052                    String date = header.get(ImapConstants.RFC822_DATE);
053                    String subject = header.get(ImapConstants.RFC822_SUBJECT);
054                    Address[] fromAddresses = buildAddresses(header
055                                    .get(ImapConstants.RFC822_FROM));
056                    Address[] senderAddresses = buildAddresses(header
057                                    .get(ImapConstants.RFC822_SENDER), fromAddresses);
058                    Address[] replyToAddresses = buildAddresses(header
059                                    .get(ImapConstants.RFC822_REPLY_TO), fromAddresses);
060                    Address[] toAddresses = buildAddresses(header
061                                    .get(ImapConstants.RFC822_TO));
062                    Address[] ccAddresses = buildAddresses(header
063                                    .get(ImapConstants.RFC822_CC));
064                    Address[] bccAddresses = buildAddresses(header
065                                    .get(ImapConstants.RFC822_BCC)); 
066                    String inReplyTo = header.get(ImapConstants.RFC822_IN_REPLY_TO);
067                    String messageId = header.get(ImapConstants.RFC822_MESSAGE_ID);
068                    Envelope envelope = new Envelope(date, subject, fromAddresses,
069                                    senderAddresses, replyToAddresses, toAddresses, ccAddresses,
070                                    bccAddresses, inReplyTo, messageId);
071                    return envelope;
072            }
073            
074            private Address[] buildAddresses(String value, Address[] defaults) {
075                    Address[] addresses = buildAddresses(value);
076                    return (null == addresses) ? defaults : addresses;
077            }
078            
079            private Address[] buildAddresses(String value) {
080                    try {
081                            return buildMailAddresses(value);
082                    } catch (ParseException ex) {
083                            logger.warn(ex.getMessage());
084                            return null;
085                    }
086            }
087            
088            private Address[] buildMailAddresses(String value) throws ParseException {
089                    if (StringUtils.isEmpty(value)) {
090                            return null;
091                    } else {
092                            AddressList addressList = AddressList.parse(value);
093                            int size = addressList.size();
094                            List<Address> addresses = new ArrayList<Address>(size);
095                            for (int i = 0; i < size; i++) {
096                                    org.apache.james.mime4j.field.address.Address address = addressList
097                                                    .get(i);
098                                    if (address instanceof Group) {
099                                            addAddresses((Group) address, addresses);
100                                    } else if (address instanceof Mailbox) {
101                                            Address mailboxAddress = buildAddress((Mailbox) address);
102                                            addresses.add(mailboxAddress);
103                                    } else {
104                                            logger.warn("Unknown address type");
105                                    }
106                            }
107                            return addresses.toArray(Address.EMPTY);
108                    }
109            }
110            
111            private void addAddresses(Group group, List<Address> addresses) {
112                    String groupName = group.getName();
113                    addresses.add(new Address(null, null, groupName, null));
114                    MailboxList mailboxList = group.getMailboxes();
115                    for (int i = 0; i < mailboxList.size(); i++) {
116                            Address mailboxAddress = buildAddress(mailboxList.get(i));
117                            addresses.add(mailboxAddress);
118                    }
119                    addresses.add(new Address(null, null, null, null));
120            }
121            
122            private Address buildAddress(Mailbox mailbox) {
123                    String name = mailbox.getName();
124                    String domain = mailbox.getDomain();
125                    DomainList route = mailbox.getRoute();
126                    String atDomainList;
127                    if (CollectionUtils.isEmpty(route)) {
128                            atDomainList = null;
129                    } else {
130                            atDomainList = route.toRouteString();
131                    }
132                    String localPart = mailbox.getLocalPart();
133                    return new Address(atDomainList, domain, localPart, name);
134            }
135    
136    }