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.util.Date; 019 020 import javax.mail.Flags; 021 022 import org.apache.commons.lang.ArrayUtils; 023 import org.jboss.netty.channel.Channel; 024 025 import com.hs.mail.imap.message.request.ImapRequest; 026 import com.hs.mail.imap.message.response.FetchResponse; 027 import com.hs.mail.imap.processor.fetch.Address; 028 import com.hs.mail.imap.processor.fetch.Content; 029 import com.hs.mail.imap.processor.fetch.Envelope; 030 import com.hs.mail.imap.processor.fetch.MimeDescriptor; 031 032 /** 033 * 034 * @author Won Chul Doh 035 * @since Mar 8, 2010 036 * 037 */ 038 public class FetchResponder extends DefaultImapResponder { 039 040 public FetchResponder(Channel channel, ImapRequest request) { 041 super(channel, request); 042 } 043 044 public void respond(FetchResponse response) { 045 untagged(response.getMessageNumber() + " " + request.getCommand()); 046 openParen("("); 047 composeFlags(response); 048 composeInternalDate(response); 049 composeSize(response); 050 composeEnvelope(response); 051 composeBody(response); 052 composeBodyStructure(response); 053 composeUid(response); 054 composeBodyContent(response); 055 closeParen(")"); 056 end(); 057 } 058 059 void composeFlags(FetchResponse response) { 060 Flags flags = response.getFlags(); 061 if (flags != null) { 062 message("FLAGS"); 063 openParen("("); 064 flags(flags); 065 closeParen(")"); 066 } 067 } 068 069 void composeInternalDate(FetchResponse response) { 070 Date internalDate = response.getInternalDate(); 071 if (internalDate != null) { 072 message("INTERNALDATE"); 073 quote(encodeDateTime(internalDate)); 074 } 075 } 076 077 void composeSize(FetchResponse response) { 078 Long size = response.getSize(); 079 if (size != null) { 080 message("RFC822.SIZE"); 081 message(size.toString()); 082 } 083 } 084 085 void composeUid(FetchResponse response) { 086 Long uid = response.getUid(); 087 if (uid != null) { 088 message("UID"); 089 message(uid.toString()); 090 } 091 } 092 093 void composeEnvelope(Envelope envelope, boolean prefixWithName) { 094 if (envelope != null) { 095 if (prefixWithName) { 096 message("ENVELOPE"); 097 } 098 openParen("("); 099 nillableQuote(envelope.getDate()); 100 nillableQuote(envelope.getSubject()); 101 address(envelope.getFrom()); 102 address(envelope.getSender()); 103 address(envelope.getReplyTo()); 104 address(envelope.getTo()); 105 address(envelope.getCc()); 106 address(envelope.getBcc()); 107 nillableQuote(envelope.getInReplyTo()); 108 nillableQuote(envelope.getMessageId()); 109 closeParen(")"); 110 } 111 } 112 113 void composeEnvelope(FetchResponse response) { 114 Envelope envelope = response.getEnvelope(); 115 composeEnvelope(envelope, true); 116 } 117 118 void composeBody(FetchResponse response) { 119 MimeDescriptor body = response.getBody(); 120 if (body != null) { 121 message("BODY"); 122 composeStructure(body, false, false); 123 } 124 } 125 126 void composeBodyStructure(FetchResponse response) { 127 MimeDescriptor bodyStructure = response.getBodyStructure(); 128 if (bodyStructure != null) { 129 message("BODYSTRUCTURE"); 130 composeStructure(bodyStructure, true, false); 131 } 132 } 133 134 void composeStructure(MimeDescriptor descriptor, boolean includeExtensions, 135 boolean isInnerPart) { 136 String mediaType; 137 String subType; 138 if ((mediaType = descriptor.getType()) == null) { 139 mediaType = "text"; 140 subType = "plain"; 141 } else { 142 subType = descriptor.getSubType(); 143 } 144 composeStructure(descriptor, mediaType, subType, includeExtensions, 145 isInnerPart); 146 } 147 148 void composeStructure(MimeDescriptor descriptor, String mediaType, 149 String subType, boolean includeExtensions, boolean isInnerPart) { 150 openParen("("); 151 if ("multipart".equalsIgnoreCase(mediaType)) { 152 composeMultipart(descriptor, mediaType, subType, includeExtensions); 153 } else if ("message".equalsIgnoreCase(mediaType) 154 && "rfc822".equalsIgnoreCase(subType)) { 155 composeRfc822(descriptor, mediaType, subType, includeExtensions); 156 } else { 157 composeBasic(descriptor, mediaType, subType, includeExtensions); 158 } 159 closeParen(")"); 160 } 161 162 void composeMultipart(MimeDescriptor descriptor, String mediaType, 163 String subType, boolean includeExtensions) { 164 for (MimeDescriptor part : descriptor.getParts()) { 165 composeStructure(part, includeExtensions, true); 166 } 167 quoteUpper(subType); 168 if (includeExtensions) { 169 nillableQuotes(descriptor.getParameters()); 170 composeDisposition(descriptor); 171 nillableQuotes(descriptor.getLanguages()); 172 nillableQuote(descriptor.getLocation()); 173 } 174 } 175 176 void composeRfc822(MimeDescriptor descriptor, String mediaType, 177 String subType, boolean includeExtensions) { 178 composeBodyFields(descriptor, mediaType, subType); 179 composeEnvelope(descriptor.getEnvelope(), false); 180 composeStructure(descriptor.getEmbeddedMessageDescriptor(), 181 includeExtensions, true); 182 message(descriptor.getLines()); 183 if (includeExtensions) { 184 encodeOnePartBodyExtensions(descriptor); 185 } 186 } 187 188 void composeBasic(MimeDescriptor descriptor, String mediaType, 189 String subType, boolean includeExtensions) { 190 composeBodyFields(descriptor, mediaType, subType); 191 if ("text".equalsIgnoreCase(mediaType)) { 192 message(descriptor.getLines()); 193 } 194 if (includeExtensions) { 195 encodeOnePartBodyExtensions(descriptor); 196 } 197 } 198 199 void encodeOnePartBodyExtensions(MimeDescriptor descriptor) { 200 nillableQuote(descriptor.getMd5()); 201 composeDisposition(descriptor); 202 nillableQuotes(descriptor.getLanguages()); 203 nillableQuote(descriptor.getLocation()); 204 } 205 206 void composeBodyFields(MimeDescriptor descriptor, String mediaType, 207 String subType) { 208 quoteUpper(mediaType); 209 quoteUpper(subType); 210 nillableQuotes(descriptor.getParameters()); 211 nillableQuote(descriptor.getId()); 212 nillableQuote(descriptor.getDescription()); 213 quoteUpper(descriptor.getEncoding()); 214 message(descriptor.getBodyOctets()); 215 } 216 217 void composeDisposition(MimeDescriptor descriptor) { 218 String disposition = descriptor.getDisposition(); 219 if (disposition == null) { 220 nil(); 221 } else { 222 openParen("("); 223 quote(disposition); 224 nillableQuotes(descriptor.getDispositionParams()); 225 closeParen(")"); 226 } 227 } 228 229 void composeBodyContent(FetchResponse response) { 230 Content content = response.getContent(); 231 if (content != null) { 232 message(content.getName()); 233 literal(content); 234 } 235 } 236 237 void address(Address[] addresses) { 238 if (ArrayUtils.isEmpty(addresses)) { 239 nil(); 240 } else { 241 openParen("("); 242 for (int i = 0; i < addresses.length; i++) { 243 skipNextSpace(); 244 openParen("("); 245 nillableQuote(addresses[i].getPersonalName()); 246 nillableQuote(addresses[i].getAtDomainList()); 247 nillableQuote(addresses[i].getMailboxName()); 248 nillableQuote(addresses[i].getHostName()); 249 closeParen(")"); 250 } 251 closeParen(")"); 252 } 253 } 254 255 }