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.server.codec;
017    
018    import java.text.DateFormat;
019    import java.text.ParseException;
020    import java.text.SimpleDateFormat;
021    import java.util.Date;
022    import java.util.Locale;
023    
024    import javax.mail.Flags;
025    
026    import com.hs.mail.imap.message.SequenceRange;
027    import com.hs.mail.imap.message.request.Status;
028    
029    /**
030     * 
031     * @author Won Chul Doh
032     * @since Jan 22, 2010
033     *
034     */
035    public class DecoderUtils {
036    
037            public static void decodeFlagList(String flagString, final Flags flags) {
038                    if (flagString.equalsIgnoreCase("\\Answered")) {
039                            flags.add(Flags.Flag.ANSWERED);
040                    } else if (flagString.equalsIgnoreCase("\\Flagged")) {
041                            flags.add(Flags.Flag.FLAGGED);
042                    } else if (flagString.equalsIgnoreCase("\\Deleted")) {
043                            flags.add(Flags.Flag.DELETED);
044                    } else if (flagString.equalsIgnoreCase("\\Seen")) {
045                            flags.add(Flags.Flag.SEEN);
046                    } else if (flagString.equalsIgnoreCase("\\Draft")) {
047                            flags.add(Flags.Flag.DRAFT);
048                    } else {
049                            if (flagString.equalsIgnoreCase("\\Recent")) {
050                                    // RFC3501 specifically excludes /Recent
051                                    // The /Recent flag should be set automatically by the server
052                            } else {
053                                    // RFC3501 allows novel flags
054                                    flags.add(flagString);
055                            }
056                    }
057            }
058    
059            private static final DateFormat DATE_FORMAT0;
060            private static final DateFormat DATE_FORMAT1;
061            private static final DateFormat DATE_FORMAT2;
062            static {
063                    DATE_FORMAT0 = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
064                    DATE_FORMAT1 = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss ZZZZ",
065                                    Locale.US);
066                    DATE_FORMAT2 = new SimpleDateFormat(" d-MMM-yyyy HH:mm:ss ZZZZ",
067                                    Locale.US);
068            }
069    
070            public static Date parseDate(String date) throws ParseException {
071                    DateFormat df = DATE_FORMAT0;
072                    return df.parse(date);
073            }
074    
075            public static Date parseDateTime(String dateTime) throws ParseException {
076                    String tz = dateTime.substring(21);
077                    tz = "GMT" + tz.charAt(0) + tz.charAt(1) + tz.charAt(2) + ":"
078                                    + tz.charAt(3) + tz.charAt(4);
079                    dateTime = dateTime.substring(0, 21) + tz;
080                    DateFormat df = (dateTime.charAt(0) != ' ') ? DATE_FORMAT1
081                                    : DATE_FORMAT2;
082                    return df.parse(dateTime);
083            }
084            
085            public static void decodeStatusAttList(String statusAtt,
086                            Status statusAtts) {
087                    String val = statusAtt.toUpperCase();
088                    if ("MESSAGES".equals(val)) {
089                            statusAtts.setMessages(true);
090                    } else if ("RECENT".equals(val)) {
091                            statusAtts.setRecent(true);
092                    } else if ("UIDNEXT".equals(val)) {
093                            statusAtts.setUidNext(true);
094                    } else if ("UIDVALIDITY".equals(val)) {
095                            statusAtts.setUidValidity(true);
096                    } else if ("UNSEEN".equals(val)) {
097                            statusAtts.setUnseen(true);
098                    }
099            }
100            
101            public static SequenceRange parseSeqRange(String range) {
102                    int pos = range.indexOf(':');
103                    if (pos == -1) {
104                            long value = parseSeqNumber(range);
105                            return new SequenceRange(value);
106                    } else {
107                            long min = parseSeqNumber(range.substring(0, pos));
108                            long max = parseSeqNumber(range.substring(pos + 1));
109                            return new SequenceRange(Math.min(min, max), Math.max(min, max));
110                    }
111            }
112            
113            private static long parseSeqNumber(String value) {
114                    if (value.length() == 1 && value.charAt(0) == '*') {
115                            return Long.MAX_VALUE;
116                    }
117                    return Long.parseLong(value);
118            }
119    
120    }