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.message.responder;
017    
018    import java.nio.ByteBuffer;
019    import java.util.Date;
020    import java.util.List;
021    import java.util.Locale;
022    import java.util.TimeZone;
023    
024    import javax.mail.Flags;
025    
026    import org.apache.commons.lang.ArrayUtils;
027    import org.apache.commons.lang.time.FastDateFormat;
028    import org.jboss.netty.channel.Channel;
029    import org.jboss.netty.channel.ChannelFuture;
030    import org.springframework.util.CollectionUtils;
031    
032    import com.hs.mail.imap.message.request.ImapRequest;
033    import com.hs.mail.imap.message.response.ImapResponse;
034    import com.hs.mail.imap.processor.fetch.Content;
035    
036    /**
037     * 
038     * @author Won Chul Doh
039     * @since Mar 17, 2010
040     *
041     */
042    public abstract class AbstractImapResponder implements Responder {
043            
044            protected Channel channel;
045            protected ImapRequest request;
046            
047            private boolean skipNextSpace;
048    
049            protected AbstractImapResponder(Channel channel, ImapRequest request) {
050                    super();
051                    this.channel = channel;
052                    this.request = request;
053                    this.skipNextSpace = false;
054            }
055    
056            public Channel getChannel() {
057                    return channel;
058            }
059            
060            public ImapRequest getRequest() {
061                    return request;
062            }
063            
064            ChannelFuture write(Object message) {
065                    return channel.write(message);
066            }
067    
068            public ChannelFuture okCompleted(ImapRequest request) {
069                    return write(request.getTag() + " OK " + request.getCommand()
070                                    + " completed\r\n");
071            }
072            
073            public ChannelFuture okCompleted(ImapRequest request, String responseCode) {
074                    return write(request.getTag() + " OK " + responseCode + " "
075                                    + request.getCommand() + " completed\r\n");
076            }
077    
078            public ChannelFuture bye(String text) {
079                    return write("* BYE " + text + "\r\n");
080            }
081    
082            public ChannelFuture taggedNo(ImapRequest request, String text) {
083                    return write(request.getTag() + " NO " + request.getCommand()
084                                    + " failed. " + text + "\r\n");
085            }
086    
087            public ChannelFuture taggedNo(ImapRequest request, String responseCode,
088                            String text) {
089                    return write(request.getTag() + " NO " + responseCode + " "
090                                    + request.getCommand() + " failed. " + text + "\r\n");
091            }
092    
093            public ChannelFuture untaggedOK(String text) {
094                    return write("* OK " + text + "\r\n");
095            }
096    
097            public ChannelFuture untagged(String text) {
098                    return write("* " + text);
099            }
100    
101            protected void message(String message) {
102                    space();
103                    write(message);
104            }
105            
106            protected void message(long number) {
107                    space();
108                    write(Long.toString(number));
109            }
110            
111            protected void space() {
112                    if (skipNextSpace)
113                            skipNextSpace = false;
114                    else
115                            write(" ");
116            }
117            
118            protected void skipNextSpace() {
119                    skipNextSpace = true;
120            }
121            
122            protected void openParen(String bracket) {
123                    space();
124                    write(bracket);
125                    skipNextSpace();
126            }
127            
128            protected void closeParen(String bracket) {
129                    write(bracket);
130            }
131            
132            protected void end() {
133                    write("\r\n");
134            }
135            
136            protected void quote(String message) {
137                    message("\"" + message + "\"");
138            }
139            
140            protected void quoteUpper(String message) {
141                    quote(message.toUpperCase());
142            }
143            
144            protected void nil() {
145                    message(ImapResponse.NIL);
146            }
147            
148            protected void nillableQuote(String message) {
149                    if (null == message) {
150                            nil();
151                    } else {
152                            quote(message);
153                    }
154            }
155            
156            protected void nillableQuotes(List<String> quotes) {
157                    if (CollectionUtils.isEmpty(quotes)) {
158                            nil();
159                    } else {
160                            openParen("(");
161                            for (String message : quotes) {
162                                    nillableQuote(message);
163                            }
164                            closeParen(")");
165                    }
166            }
167            
168            protected void flags(Flags flags) {
169                    if (flags.contains(Flags.Flag.ANSWERED)) {
170                            message("\\Answered");
171                    }
172                    if (flags.contains(Flags.Flag.DELETED)) {
173                            message("\\Deleted");
174                    }
175                    if (flags.contains(Flags.Flag.DRAFT)) {
176                            message("\\Draft");
177                    }
178                    if (flags.contains(Flags.Flag.FLAGGED)) {
179                            message("\\Flagged");
180                    }
181                    if (flags.contains(Flags.Flag.RECENT)) {
182                            message("\\Recent");
183                    }
184                    if (flags.contains(Flags.Flag.SEEN)) {
185                            message("\\Seen");
186                    }
187                    String[] ufs = flags.getUserFlags();
188                    if (!ArrayUtils.isEmpty(ufs)) {
189                            for (String uf : ufs) {
190                                    message(uf);
191                            }
192                    }
193                    skipNextSpace = false;
194            }
195            
196            protected String encodeDateTime(Date date) {
197                    FastDateFormat df = FastDateFormat.getInstance(
198                                    "dd-MMM-yyyy HH:mm:ss Z", TimeZone.getTimeZone("GMT"),
199                                    Locale.US);
200                    return df.format(date);
201            }
202            
203            protected void literal(Content content) {
204                    long size = content.getSize();
205                    message("{" + size + "}\r\n");
206                    if (size > 0) {
207                            ByteBuffer contents = content.getContents();
208                            write(contents);
209                    }
210            }
211    
212    }