1 36 package org.columba.ristretto.imap; 37 38 import java.io.IOException ; 39 import java.io.InputStream ; 40 import java.io.OutputStream ; 41 import java.nio.charset.Charset ; 42 import java.util.Arrays ; 43 import java.util.Iterator ; 44 45 import org.columba.ristretto.io.StreamUtils; 46 47 57 public class IMAPCommand { 58 private String tag; 59 60 private String command; 61 62 private Object [] parameters; 63 64 private boolean lastWasLiteral; 65 66 private Charset charset; 67 68 74 public IMAPCommand(String tag, String command, Object [] parameters) { 75 this(tag, command, parameters, Charset.forName("ISO-8859-1")); 76 } 77 78 84 public IMAPCommand(String tag, String command) { 85 this(tag, command, null); 86 } 87 88 98 public void writeToStream(IMAPInputStream in, OutputStream out) 99 throws IMAPException, IOException { 100 Object arg; 101 out.write(tag.getBytes("US-ASCII")); 102 out.write(' '); 103 out.write(command.getBytes("US-ASCII")); 104 if (parameters != null) { 106 Iterator it = Arrays.asList(parameters).iterator(); 107 while (it.hasNext()) { 108 out.write(' '); 109 arg = it.next(); 110 if (arg instanceof String ) { 111 writeString((String ) arg, in, out); 112 } else if (arg instanceof String []) { 113 writeStringArray((String []) arg, in, out); 114 } else if (arg instanceof InputStream ) { 115 writeInputStream((InputStream ) arg, in, out); 116 } else if (arg instanceof SearchKey) { 117 writeSearchKey((SearchKey) arg, in, out); 118 } else if (arg instanceof byte[]) { 119 writeByteArray(((byte[]) arg), in, out); 120 } else if (arg instanceof Integer []) { 121 writeAddress(((Integer []) arg), in, out); 122 } else if (arg instanceof char[]) { 123 writeCharArray(((char[]) arg), in, out); 124 } else if (arg instanceof Section) { 125 writeSection((Section) arg, in, out); 126 } else { 127 writeCharArray(arg.toString().toCharArray(), in, out); 128 } 129 } 130 } 131 132 out.write('\r'); 133 out.write('\n'); 134 out.flush(); 135 } 136 137 private void writeSearchKey(SearchKey key, IMAPInputStream in, 138 OutputStream out) throws IOException , IMAPException { 139 String [] strings = key.toStringArray(); 140 141 if (strings.length > 1) { 142 out.write('('); 143 out.write(strings[0].getBytes(charset.name())); 144 for (int i = 1; i < strings.length; i++) { 145 out.write(' '); 146 writeString(strings[i], in, out); 147 } 148 out.write(')'); 149 } else if (strings.length == 1) { 150 writeString(strings[0], in, out); 151 } 152 153 } 154 155 private void writeSection(Section section, IMAPInputStream in, 156 OutputStream out) throws IMAPException, IOException { 157 Object arg; 158 out.write('('); 159 out.write(section.getType().getBytes("US-ASCII")); 160 out.write('['); 161 162 Iterator it = Arrays.asList(section.getParams()).iterator(); 163 while (it.hasNext()) { 164 arg = it.next(); 165 if (arg instanceof String ) { 166 writeString((String ) arg, in, out); 167 if (it.hasNext()) 168 out.write(' '); 169 } else if (arg instanceof String []) { 170 writeStringArray((String []) arg, in, out); 171 } else if (arg instanceof Integer []) { 172 writeAddress((Integer []) arg, in, out); 173 } else { 174 writeCharArray(arg.toString().toCharArray(), in, out); 175 } 176 } 177 178 out.write(']'); 179 out.write(')'); 180 lastWasLiteral = false; 181 } 182 183 188 private void writeCharArray(char[] cs, IMAPInputStream in, OutputStream out) 189 throws IMAPException, IOException { 190 for (int i = 0; i < cs.length; i++) { 191 out.write(cs[i]); 192 } 193 } 194 195 200 private void writeAddress(Integer [] integers, IMAPInputStream in, 201 OutputStream out) throws IMAPException, IOException { 202 203 out.write(new Integer (integers[0].intValue() + 1).toString().getBytes( 204 charset.name())); 205 for (int i = 1; i < integers.length; i++) { 206 out.write('.'); 207 out.write(new Integer (integers[i].intValue() + 1).toString() 208 .getBytes(charset.name())); 209 } 210 211 lastWasLiteral = false; 212 } 213 214 219 private void writeByteArray(byte[] bs, IMAPInputStream in, OutputStream out) 220 throws IMAPException, IOException { 221 out.write('{'); 222 out.write(Integer.toString(bs.length).getBytes(charset.name())); 223 out.write('}'); 224 out.write('\r'); 225 out.write('\n'); 226 out.flush(); 227 IMAPResponse response = in.readResponse(); 228 if (response.getResponseType() != IMAPResponse.RESPONSE_CONTINUATION) 229 throw new IMAPException(response); 230 231 out.write(bs); 232 out.flush(); 233 lastWasLiteral = true; 234 } 235 236 240 private void writeInputStream(InputStream stream, IMAPInputStream in, 241 OutputStream out) throws IMAPException, IOException { 242 int size = 1000; 243 244 out.write('{'); 245 out 246 .write(Integer.toString(stream.available()).getBytes( 247 charset.name())); 248 out.write('}'); 250 out.write('\r'); 251 out.write('\n'); 252 out.flush(); 253 254 IMAPResponse response = in.readResponse(); 255 if (response.getResponseType() != IMAPResponse.RESPONSE_CONTINUATION) 256 throw new IMAPException(response); 257 258 StreamUtils.streamCopy(stream, out, 1400); 260 261 266 lastWasLiteral = true; 267 } 268 269 273 private void writeStringArray(String [] strings, IMAPInputStream in, 274 OutputStream out) throws IMAPException, IOException { 275 out.write('('); 276 if (strings.length > 0) { 277 out.write(strings[0].getBytes(charset.name())); 278 for (int i = 1; i < strings.length; i++) { 279 out.write(' '); 280 writeString(strings[i], in, out); 281 } 282 } 283 out.write(')'); 284 lastWasLiteral = false; 285 } 286 287 290 private void writeString(String sequence, IMAPInputStream in, 291 OutputStream out) throws IMAPException, IOException { 292 boolean plainSafe = true; 294 boolean quote = sequence.length() == 0; 295 296 int i = 0; 297 while (i < sequence.length() && plainSafe) { 298 plainSafe &= sequence.charAt(i) < 128; 299 plainSafe &= sequence.charAt(i) != '\"'; 300 plainSafe &= sequence.charAt(i) != '\\'; 301 plainSafe &= sequence.charAt(i) != '\0'; 302 plainSafe &= sequence.charAt(i) != '\r'; 303 plainSafe &= sequence.charAt(i) != '\n'; 304 305 quote |= sequence.charAt(i) == ' '; 306 quote |= sequence.charAt(i) == '('; 307 quote |= sequence.charAt(i) == ')'; 308 quote |= sequence.charAt(i) == '{'; 309 quote |= sequence.charAt(i) == '%'; 310 quote |= sequence.charAt(i) == '*'; 311 quote |= sequence.charAt(i) == ']'; 312 314 i++; 315 } 316 if (plainSafe) { 318 if (quote) { 319 out.write('\"'); 320 } 321 out.write(sequence.getBytes(charset.name())); 322 if (quote) { 323 out.write('\"'); 324 } 325 lastWasLiteral = false; 326 } else { 327 writeByteArray(sequence.getBytes(charset.name()), in, out); 328 } 329 } 330 331 336 public String getTag() { 337 return tag; 338 } 339 340 348 public IMAPCommand(String tag, String command, Object [] parameters, 349 Charset charset) { 350 this.tag = tag; 351 this.command = command; 352 this.parameters = parameters; 353 this.charset = charset; 354 } 355 356 363 public int estimateLength() { 364 int estimatedLength = command.length() + tag.length() + 1; 366 367 if (parameters != null) { 369 for (int i = 0; i < parameters.length; i++) { 370 if (parameters[i] instanceof char[]) { 372 estimatedLength += ((char[]) parameters[i]).length; 373 } 374 375 else if (parameters[i] instanceof String ) { 376 estimatedLength += ((String ) parameters[i]).length(); 377 } 378 379 else if (parameters[i] instanceof String []) { 380 String [] strings = (String []) parameters[i]; 381 for (int j = 0; j < strings.length; j++) { 382 estimatedLength += strings[j].length(); 383 } 384 } 385 386 else if (parameters[i] instanceof SearchKey) { 387 String [] strings = ((SearchKey) parameters[i]) 388 .toStringArray(); 389 for (int j = 0; j < strings.length; j++) { 390 estimatedLength += strings[j].length(); 391 } 392 } 393 394 else { 395 estimatedLength += 3; 397 } 398 399 estimatedLength++; 401 } 402 } 403 404 return estimatedLength; 405 } 406 } | Popular Tags |