1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.geronimo.javamail.store.imap.connection;
19
20 import java.io.ByteArrayOutputStream;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.io.UnsupportedEncodingException;
25 import java.text.SimpleDateFormat;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.Vector;
30
31 import javax.mail.FetchProfile;
32 import javax.mail.Flags;
33 import javax.mail.Message;
34 import javax.mail.MessagingException;
35 import javax.mail.Quota;
36 import javax.mail.UIDFolder;
37
38 import javax.mail.search.AddressTerm;
39 import javax.mail.search.AndTerm;
40 import javax.mail.search.BodyTerm;
41 import javax.mail.search.ComparisonTerm;
42 import javax.mail.search.DateTerm;
43 import javax.mail.search.FlagTerm;
44 import javax.mail.search.FromTerm;
45 import javax.mail.search.FromStringTerm;
46 import javax.mail.search.HeaderTerm;
47 import javax.mail.search.MessageIDTerm;
48 import javax.mail.search.MessageNumberTerm;
49 import javax.mail.search.NotTerm;
50 import javax.mail.search.OrTerm;
51 import javax.mail.search.ReceivedDateTerm;
52 import javax.mail.search.RecipientTerm;
53 import javax.mail.search.RecipientStringTerm;
54 import javax.mail.search.SearchException;
55 import javax.mail.search.SearchTerm;
56 import javax.mail.search.SentDateTerm;
57 import javax.mail.search.SizeTerm;
58 import javax.mail.search.StringTerm;
59 import javax.mail.search.SubjectTerm;
60
61 import org.apache.geronimo.javamail.store.imap.ACL;
62 import org.apache.geronimo.javamail.store.imap.IMAPFolder;
63 import org.apache.geronimo.javamail.store.imap.Rights;
64 import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
65
66 import org.apache.geronimo.javamail.util.CommandFailedException;
67
68
69
70
71
72
73
74
75 public class IMAPCommand {
76
77
78
79 public static final char[] encodingTable = {
80 'A', 'B', 'C', 'D', 'E', 'F', 'G',
81 'H', 'I', 'J', 'K', 'L', 'M', 'N',
82 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
83 'V', 'W', 'X', 'Y', 'Z',
84 'a', 'b', 'c', 'd', 'e', 'f', 'g',
85 'h', 'i', 'j', 'k', 'l', 'm', 'n',
86 'o', 'p', 'q', 'r', 's', 't', 'u',
87 'v', 'w', 'x', 'y', 'z',
88 '0', '1', '2', '3', '4', '5', '6',
89 '7', '8', '9',
90 '+', ','
91 };
92
93 protected boolean needWhiteSpace = false;
94
95
96 protected DataOutputStream out;
97
98 protected ByteArrayOutputStream sink;
99
100
101 protected List segments = null;
102
103 protected String tag;
104
105
106 static protected int tagCounter = 0;
107
108
109
110
111 public IMAPCommand() {
112 try {
113 sink = new ByteArrayOutputStream();
114 out = new DataOutputStream(sink);
115
116
117 out.writeBytes(getTag());
118
119 out.write(' ');
120 } catch (IOException e ) {
121 }
122 }
123
124
125
126
127
128
129 public IMAPCommand(String command) {
130 this();
131 append(command);
132 }
133
134 public String getTag() {
135 if (tag == null) {
136
137 tag = "a" + tagCounter++;
138 }
139 return tag;
140 }
141
142
143
144
145
146
147
148
149 private void saveCurrentSegment()
150 {
151 try {
152 out.flush();
153
154 byte[] segment = sink.toByteArray();
155 sink.reset();
156
157 if (segments == null) {
158 segments = new ArrayList();
159 }
160
161 segments.add(segment);
162 } catch (IOException e) {
163 }
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177 public void writeTo(OutputStream outStream, IMAPConnection connection) throws IOException, MessagingException
178 {
179
180
181 if (segments == null) {
182
183 out.flush();
184
185 sink.writeTo(outStream);
186
187 outStream.write('\r');
188 outStream.write('\n');
189 }
190
191
192 else {
193
194
195
196
197 for (int i = 0; i < segments.size(); i++) {
198 outStream.write((byte [])segments.get(i));
199
200
201
202
203 IMAPTaggedResponse response = connection.receiveResponse();
204 if (!response.isContinuation()) {
205 throw new CommandFailedException("Error response received on a IMAP continued command: " + response);
206 }
207 }
208 out.flush();
209
210
211 sink.writeTo(outStream);
212
213 outStream.write('\r');
214 outStream.write('\n');
215 }
216 }
217
218
219
220
221
222
223
224
225 public void append(String value) {
226 try {
227
228 out.writeBytes(value);
229
230 needWhiteSpace = true;
231 } catch (IOException e) {
232 }
233 }
234
235
236
237
238
239
240
241
242
243
244 public void appendString(String value) {
245
246 appendString(value.getBytes());
247 }
248
249
250
251
252
253
254
255
256 public void appendQuotedString(String value) {
257
258 appendQuotedString(value.getBytes());
259 }
260
261
262
263
264
265
266
267
268
269
270 public void appendEncodedString(String value) {
271
272 value = encode(value);
273
274 appendString(value.getBytes());
275 }
276
277
278
279
280
281
282
283
284
285 public String encode(String original) {
286
287
288 byte[] buffer = new byte[4];
289 int bufferCount = 0;
290
291 StringBuffer result = new StringBuffer();
292
293
294 boolean encoding = false;
295
296 for (int i = 0; i < original.length(); i++) {
297 char ch = original.charAt(i);
298
299
300 if (encoding) {
301
302 if (ch > 31 && ch < 127) {
303
304 encode(buffer, bufferCount, result);
305
306 result.append('-');
307 encoding = false;
308
309 }
310
311 else {
312
313 buffer[++bufferCount] = (byte)(ch >> 8);
314 buffer[++bufferCount] = (byte)(ch & 0xff);
315
316 if (bufferCount >= 3) {
317 bufferCount = encode(buffer, bufferCount, result);
318 }
319
320 continue;
321 }
322 }
323
324 if (ch == '&') {
325
326 result.append('&');
327 result.append('-');
328 }
329
330 else if (ch > 31 && ch < 127) {
331
332 result.append(ch);
333 }
334 else {
335
336 result.append('&');
337
338
339
340
341 buffer[0] = (byte)(ch >> 8);
342 buffer[1] = (byte)(ch & 0xff);
343 bufferCount = 2;
344 encoding = true;
345 }
346 }
347
348 if (encoding) {
349
350 encode(buffer, bufferCount, result);
351
352 result.append('-');
353 }
354
355 return result.toString();
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370 protected static int encode(byte[] buffer, int count, StringBuffer result) {
371 byte b1 = 0;
372 byte b2 = 0;
373 byte b3 = 0;
374
375
376 switch (count) {
377
378 case 0:
379
380 return 0;
381
382
383 case 1:
384 b1 = buffer[0];
385 result.append(encodingTable[(b1 >>> 2) & 0x3f]);
386 result.append(encodingTable[(b1 << 4) & 0x30]);
387 return 0;
388
389
390 case 2:
391 b1 = buffer[0];
392 b2 = buffer[1];
393 result.append(encodingTable[(b1 >>> 2) & 0x3f]);
394 result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
395 result.append(encodingTable[((b2 << 2) & (0x3c))]);
396 return 0;
397
398
399 case 3:
400 case 4:
401 b1 = buffer[0];
402 b2 = buffer[1];
403 b3 = buffer[2];
404 result.append(encodingTable[(b1 >>> 2) & 0x3f]);
405 result.append(encodingTable[((b1 << 4) & 0x30) + ((b2 >>>4) & 0x0f)]);
406 result.append(encodingTable[((b2 << 2) & 0x3c) + ((b3 >>> 6) & 0x03)]);
407 result.append(encodingTable[b3 & 0x3f]);
408
409
410
411 if (count == 4) {
412 buffer[0] = buffer[4];
413 return 1;
414 }
415 return 0;
416 }
417 return 0;
418 }
419
420
421
422
423
424
425
426
427
428
429 public void appendString(String value, String charset) throws MessagingException {
430 if (charset == null) {
431
432 appendString(value.getBytes());
433 }
434 else {
435 try {
436
437 appendString(value.getBytes(charset));
438 } catch (UnsupportedEncodingException e) {
439 throw new MessagingException("Invalid text encoding");
440 }
441 }
442 }
443
444
445
446
447
448
449
450
451
452
453 public void appendString(byte[] value) {
454
455 switch (IMAPResponseTokenizer.getEncoding(value)) {
456 case Token.LITERAL:
457 appendLiteral(value);
458 break;
459 case Token.QUOTEDSTRING:
460 appendQuotedString(value);
461 break;
462 case Token.ATOM:
463 appendAtom(value);
464 break;
465 }
466 }
467
468
469
470
471
472
473
474
475 public void appendInteger(int value) {
476 appendAtom(Integer.toString(value));
477 }
478
479
480
481
482
483
484
485
486 public void appendLong(long value) {
487 appendAtom(Long.toString(value));
488 }
489
490
491
492
493
494
495
496
497 public void appendAtom(String value) {
498 appendAtom(value.getBytes());
499 }
500
501
502
503
504
505
506
507
508
509
510 public void appendAtom(byte[] value) {
511 try {
512
513 conditionalWhitespace();
514
515 out.write(value);
516 } catch (IOException e) {
517 }
518 }
519
520
521
522
523
524
525
526
527
528
529 public void appendLiteral(byte[] value) {
530 try {
531 appendLiteralHeader(value.length);
532 out.write(value);
533 } catch (IOException e) {
534 }
535 }
536
537
538
539
540
541
542
543
544 protected void appendLiteralHeader(int size) {
545 try {
546 conditionalWhitespace();
547 out.writeByte('{');
548 out.writeBytes(Integer.toString(size));
549 out.writeBytes("}\r\n");
550
551
552
553 saveCurrentSegment();
554 } catch (IOException e) {
555 }
556 }
557
558
559
560
561
562
563
564
565 public void appendLiteral(ByteArrayOutputStream value) {
566 try {
567 appendLiteralHeader(value.size());
568
569 value.writeTo(out);
570 } catch (IOException e) {
571 }
572 }
573
574
575
576
577
578
579
580
581 public void appendQuotedString(byte[] value) {
582 try {
583 conditionalWhitespace();
584 out.writeByte('"');
585
586
587 for (int i = 0; i < value.length; i++) {
588 byte ch = value[i];
589
590 if (ch == '"' || ch == '\\') {
591 out.writeByte('\\');
592 }
593 out.writeByte(ch);
594 }
595
596 out.writeByte('"');
597 } catch (IOException e) {
598 }
599 }
600
601
602
603
604
605
606
607 public void startList() {
608 try {
609 conditionalWhitespace();
610 out.writeByte('(');
611 needWhiteSpace = false;
612 } catch (IOException e) {
613 }
614 }
615
616
617
618
619 public void endList() {
620 try {
621 out.writeByte(')');
622 needWhiteSpace = true;
623 } catch (IOException e) {
624 }
625 }
626
627
628
629
630
631
632
633 protected void conditionalWhitespace() {
634 try {
635 if (needWhiteSpace) {
636 out.writeByte(' ');
637 }
638
639
640 needWhiteSpace = true;
641 } catch (IOException e) {
642 }
643 }
644
645
646
647
648
649
650
651
652
653 public void appendBodySection(String section, String partName) {
654 try {
655
656 if (section == null) {
657 appendBodySection(partName);
658 return;
659 }
660
661 out.writeByte('[');
662 out.writeBytes(section);
663 if (partName != null) {
664 out.writeByte('.');
665 out.writeBytes(partName);
666 }
667 out.writeByte(']');
668 needWhiteSpace = true;
669 } catch (IOException e) {
670 }
671 }
672
673
674
675
676
677
678
679
680 public void appendBodySection(String partName) {
681 try {
682 out.writeByte('[');
683 out.writeBytes(partName);
684 out.writeByte(']');
685 needWhiteSpace = true;
686 } catch (IOException e) {
687 }
688 }
689
690
691
692
693
694
695
696 public void appendFlags(Flags flags) {
697 startList();
698
699 Flags.Flag[] systemFlags = flags.getSystemFlags();
700
701
702 for (int i = 0; i < systemFlags.length; i++) {
703 Flags.Flag flag = systemFlags[i];
704
705 if (flag == Flags.Flag.ANSWERED) {
706 appendAtom("\\Answered");
707 }
708 else if (flag == Flags.Flag.DELETED) {
709 appendAtom("\\Deleted");
710 }
711 else if (flag == Flags.Flag.DRAFT) {
712 appendAtom("\\Draft");
713 }
714 else if (flag == Flags.Flag.FLAGGED) {
715 appendAtom("\\Flagged");
716 }
717 else if (flag == Flags.Flag.RECENT) {
718 appendAtom("\\Recent");
719 }
720 else if (flag == Flags.Flag.SEEN) {
721 appendAtom("\\Seen");
722 }
723 }
724
725
726 String[] userFlags = flags.getUserFlags();
727
728 for (int i = 0; i < userFlags.length; i++) {
729 appendAtom(userFlags[i]);
730 }
731
732
733 endList();
734 }
735
736
737
738
739
740
741
742 public void appendDate(Date d) {
743
744 IMAPDateFormat formatter = new IMAPDateFormat();
745
746 appendString(formatter.format(d));
747 }
748
749
750
751
752
753
754
755 public void appendSearchDate(Date d) {
756
757 IMAPSearchDateFormat formatter = new IMAPSearchDateFormat();
758
759 appendString(formatter.format(d));
760 }
761
762
763
764
765
766
767
768
769
770
771
772
773 public void appendSearchTerm(SearchTerm term, String charset) throws MessagingException {
774
775
776
777
778 if (term instanceof FlagTerm) {
779 appendFlag((FlagTerm)term, charset);
780 }
781
782
783 else if (term instanceof AndTerm) {
784 appendAnd((AndTerm)term, charset);
785 }
786 else if (term instanceof OrTerm) {
787 appendOr((OrTerm)term, charset);
788 }
789 else if (term instanceof NotTerm) {
790 appendNot((NotTerm)term, charset);
791 }
792
793 else if (term instanceof FromTerm) {
794 appendFrom((FromTerm)term, charset);
795 }
796 else if (term instanceof FromStringTerm) {
797 appendFrom((FromStringTerm)term, charset);
798 }
799 else if (term instanceof HeaderTerm) {
800 appendHeader((HeaderTerm)term, charset);
801 }
802 else if (term instanceof RecipientTerm) {
803 appendRecipient((RecipientTerm)term, charset);
804 }
805 else if (term instanceof RecipientStringTerm) {
806 appendRecipient((RecipientStringTerm)term, charset);
807 }
808 else if (term instanceof SubjectTerm) {
809 appendSubject((SubjectTerm)term, charset);
810 }
811 else if (term instanceof BodyTerm) {
812 appendBody((BodyTerm)term, charset);
813 }
814 else if (term instanceof SizeTerm) {
815 appendSize((SizeTerm)term, charset);
816 }
817 else if (term instanceof SentDateTerm) {
818 appendSentDate((SentDateTerm)term, charset);
819 }
820 else if (term instanceof ReceivedDateTerm) {
821 appendReceivedDate((ReceivedDateTerm)term, charset);
822 }
823 else if (term instanceof MessageIDTerm) {
824 appendMessageID((MessageIDTerm)term, charset);
825 }
826 else {
827
828 throw new SearchException("Unsupported search type");
829 }
830 }
831
832
833
834
835
836
837
838
839 protected void appendFlag(FlagTerm term, String charset) {
840
841 boolean set = term.getTestSet();
842
843 Flags flags = term.getFlags();
844 Flags.Flag[] systemFlags = flags.getSystemFlags();
845
846 String[] userFlags = flags.getUserFlags();
847
848
849
850 if (systemFlags.length == 0 && userFlags.length == 0) {
851 return;
852 }
853
854 if (set) {
855 for (int i = 0; i < systemFlags.length; i++) {
856 Flags.Flag flag = systemFlags[i];
857
858 if (flag == Flags.Flag.ANSWERED) {
859 appendAtom("ANSWERED");
860 }
861 else if (flag == Flags.Flag.DELETED) {
862 appendAtom("DELETED");
863 }
864 else if (flag == Flags.Flag.DRAFT) {
865 appendAtom("DRAFT");
866 }
867 else if (flag == Flags.Flag.FLAGGED) {
868 appendAtom("FLAGGED");
869 }
870 else if (flag == Flags.Flag.RECENT) {
871 appendAtom("RECENT");
872 }
873 else if (flag == Flags.Flag.SEEN) {
874 appendAtom("SEEN");
875 }
876 }
877 }
878 else {
879 for (int i = 0; i < systemFlags.length; i++) {
880 Flags.Flag flag = systemFlags[i];
881
882 if (flag == Flags.Flag.ANSWERED) {
883 appendAtom("UNANSWERED");
884 }
885 else if (flag == Flags.Flag.DELETED) {
886 appendAtom("UNDELETED");
887 }
888 else if (flag == Flags.Flag.DRAFT) {
889 appendAtom("UNDRAFT");
890 }
891 else if (flag == Flags.Flag.FLAGGED) {
892 appendAtom("UNFLAGGED");
893 }
894 else if (flag == Flags.Flag.RECENT) {
895
896 appendAtom("OLD");
897 }
898 else if (flag == Flags.Flag.SEEN) {
899 appendAtom("UNSEEN");
900 }
901 }
902 }
903
904
905
906 for (int i = 0; i < userFlags.length; i++) {
907 appendAtom(set ? "KEYWORD" : "UNKEYWORD");
908 appendAtom(userFlags[i]);
909 }
910 }
911
912
913
914
915
916
917
918
919
920 protected void appendAnd(AndTerm term, String charset) throws MessagingException {
921
922
923
924 SearchTerm[] terms = term.getTerms();
925
926 for (int i = 0; i < terms.length; i++) {
927 appendSearchTerm(terms[i], charset);
928 }
929 }
930
931
932
933
934
935
936
937
938
939 protected void appendOr(OrTerm term, String charset) throws MessagingException {
940 SearchTerm[] terms = term.getTerms();
941
942
943
944
945
946
947
948 if (terms.length == 1) {
949
950 appendSearchTerm(terms[0], charset);
951 return;
952 }
953
954
955 if (terms.length > 2) {
956
957 SearchTerm current = terms[0];
958
959 for (int i = 1; i < terms.length; i++) {
960 current = new OrTerm(current, terms[i]);
961 }
962
963
964 terms = ((OrTerm)current).getTerms();
965 }
966
967
968 appendAtom("OR");
969 startList();
970
971 appendSearchTerm(terms[0], charset);
972 endList();
973 startList();
974
975 appendSearchTerm(terms[0], charset);
976
977 endList();
978 }
979
980
981
982
983
984
985
986
987 protected void appendNot(NotTerm term, String charset) throws MessagingException {
988
989 appendAtom("NOT");
990 startList();
991
992 appendSearchTerm(term.getTerm(), charset);
993
994 endList();
995 }
996
997
998
999
1000
1001
1002
1003
1004 protected void appendFrom(FromTerm term, String charset) throws MessagingException {
1005 appendAtom("FROM");
1006
1007 appendString(term.getAddress().toString(), charset);
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017 protected void appendFrom(FromStringTerm term, String charset) throws MessagingException {
1018 appendAtom("FROM");
1019
1020 appendString(term.getPattern(), charset);
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030 protected void appendRecipient(RecipientTerm term, String charset) throws MessagingException {
1031 appendAtom(recipientType(term.getRecipientType()));
1032
1033 appendString(term.getAddress().toString(), charset);
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043 protected void appendRecipient(RecipientStringTerm term, String charset) throws MessagingException {
1044 appendAtom(recipientType(term.getRecipientType()));
1045
1046 appendString(term.getPattern(), charset);
1047 }
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 protected String recipientType(Message.RecipientType type) throws MessagingException {
1058 if (type == Message.RecipientType.TO) {
1059 return "TO";
1060 }
1061 if (type == Message.RecipientType.CC) {
1062 return "CC";
1063 }
1064 if (type == Message.RecipientType.BCC) {
1065 return "BCC";
1066 }
1067
1068 throw new SearchException("Unsupported RecipientType");
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078 protected void appendHeader(HeaderTerm term, String charset) throws MessagingException {
1079 appendAtom("HEADER");
1080 appendString(term.getHeaderName());
1081 appendString(term.getPattern(), charset);
1082 }
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 protected void appendSubject(SubjectTerm term, String charset) throws MessagingException {
1093 appendAtom("SUBJECT");
1094 appendString(term.getPattern(), charset);
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104 protected void appendBody(BodyTerm term, String charset) throws MessagingException {
1105 appendAtom("BODY");
1106 appendString(term.getPattern(), charset);
1107 }
1108
1109
1110
1111
1112
1113
1114
1115
1116 protected void appendSize(SizeTerm term, String charset) throws MessagingException {
1117
1118
1119
1120
1121
1122 if (term.getComparison() == ComparisonTerm.GT) {
1123 appendAtom("LARGER");
1124 appendInteger(term.getNumber());
1125 }
1126 else if (term.getComparison() == ComparisonTerm.LT) {
1127 appendAtom("SMALLER");
1128 appendInteger(term.getNumber());
1129 }
1130 else if (term.getComparison() == ComparisonTerm.EQ) {
1131 appendAtom("NOT");
1132 appendAtom("LARGER");
1133 appendInteger(term.getNumber());
1134
1135 appendAtom("NOT");
1136 appendAtom("SMALLER");
1137
1138 appendInteger(term.getNumber());
1139 }
1140 else if (term.getComparison() == ComparisonTerm.NE) {
1141
1142 appendAtom("OR");
1143 appendAtom("LARGER");
1144 appendInteger(term.getNumber());
1145
1146 appendAtom("SMALLER");
1147 appendInteger(term.getNumber());
1148 }
1149 else if (term.getComparison() == ComparisonTerm.LE) {
1150
1151 appendAtom("NOT");
1152 appendAtom("LARGER");
1153 appendInteger(term.getNumber());
1154 }
1155 else if (term.getComparison() == ComparisonTerm.GE) {
1156
1157 appendAtom("NOT");
1158 appendAtom("SMALLER");
1159 appendInteger(term.getNumber());
1160 }
1161 }
1162
1163
1164
1165
1166
1167
1168
1169
1170 protected void appendMessageID(MessageIDTerm term, String charset) throws MessagingException {
1171
1172
1173 appendAtom("HEADER");
1174 appendString("Message-ID");
1175 appendString(term.getPattern(), charset);
1176 }
1177
1178
1179
1180
1181
1182
1183
1184
1185 protected void appendSentDate(SentDateTerm term, String charset) throws MessagingException {
1186 Date date = term.getDate();
1187
1188 switch (term.getComparison()) {
1189 case ComparisonTerm.EQ:
1190 appendAtom("SENTON");
1191 appendSearchDate(date);
1192 break;
1193 case ComparisonTerm.LT:
1194 appendAtom("SENTBEFORE");
1195 appendSearchDate(date);
1196 break;
1197 case ComparisonTerm.GT:
1198 appendAtom("SENTSINCE");
1199 appendSearchDate(date);
1200 break;
1201 case ComparisonTerm.GE:
1202 appendAtom("OR");
1203 appendAtom("SENTSINCE");
1204 appendSearchDate(date);
1205 appendAtom("SENTON");
1206 appendSearchDate(date);
1207 break;
1208 case ComparisonTerm.LE:
1209 appendAtom("OR");
1210 appendAtom("SENTBEFORE");
1211 appendSearchDate(date);
1212 appendAtom("SENTON");
1213 appendSearchDate(date);
1214 break;
1215 case ComparisonTerm.NE:
1216 appendAtom("NOT");
1217 appendAtom("SENTON");
1218 appendSearchDate(date);
1219 break;
1220 default:
1221 throw new SearchException("Unsupported date comparison type");
1222 }
1223 }
1224
1225
1226
1227
1228
1229
1230
1231
1232 protected void appendReceivedDate(ReceivedDateTerm term, String charset) throws MessagingException {
1233 Date date = term.getDate();
1234
1235 switch (term.getComparison()) {
1236 case ComparisonTerm.EQ:
1237 appendAtom("ON");
1238 appendSearchDate(date);
1239 break;
1240 case ComparisonTerm.LT:
1241 appendAtom("BEFORE");
1242 appendSearchDate(date);
1243 break;
1244 case ComparisonTerm.GT:
1245 appendAtom("SINCE");
1246 appendSearchDate(date);
1247 break;
1248 case ComparisonTerm.GE:
1249 appendAtom("OR");
1250 appendAtom("SINCE");
1251 appendSearchDate(date);
1252 appendAtom("ON");
1253 appendSearchDate(date);
1254 break;
1255 case ComparisonTerm.LE:
1256 appendAtom("OR");
1257 appendAtom("BEFORE");
1258 appendSearchDate(date);
1259 appendAtom("ON");
1260 appendSearchDate(date);
1261 break;
1262 case ComparisonTerm.NE:
1263 appendAtom("NOT");
1264 appendAtom("ON");
1265 appendSearchDate(date);
1266 break;
1267 default:
1268 throw new SearchException("Unsupported date comparison type");
1269 }
1270 }
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 static public boolean checkSearchEncoding(SearchTerm term) {
1284
1285 if (term instanceof StringTerm) {
1286 return checkStringEncoding(((StringTerm)term).getPattern());
1287 }
1288
1289
1290 else if (term instanceof AddressTerm) {
1291 return checkStringEncoding(((AddressTerm)term).getAddress().toString());
1292 }
1293
1294
1295 else if (term instanceof NotTerm) {
1296 return checkSearchEncoding(((NotTerm)term).getTerm());
1297 }
1298
1299 else if (term instanceof AndTerm) {
1300 return checkSearchEncoding(((AndTerm)term).getTerms());
1301 }
1302 else if (term instanceof OrTerm) {
1303 return checkSearchEncoding(((OrTerm)term).getTerms());
1304 }
1305
1306
1307
1308 return false;
1309 }
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321 static public boolean checkSearchEncoding(SearchTerm[] terms) {
1322 for (int i = 0; i < terms.length; i++) {
1323 if (checkSearchEncoding(terms[i])) {
1324 return true;
1325 }
1326 }
1327 return false;
1328 }
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340 static public boolean checkStringEncoding(String s) {
1341 for (int i = 0; i < s.length(); i++) {
1342
1343
1344 if (s.charAt(i) > 127) {
1345 return true;
1346 }
1347 }
1348
1349 return false;
1350 }
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361 public void appendFetchProfile(FetchProfile profile) throws MessagingException {
1362
1363
1364 startList();
1365 if (profile.contains(UIDFolder.FetchProfileItem.UID)) {
1366 appendAtom("UID");
1367 }
1368 if (profile.contains(FetchProfile.Item.ENVELOPE)) {
1369
1370 appendAtom("ENVELOPE");
1371 appendAtom("INTERNALDATE");
1372 appendAtom("RFC822.SIZE");
1373 }
1374 if (profile.contains(FetchProfile.Item.FLAGS)) {
1375 appendAtom("FLAGS");
1376 }
1377 if (profile.contains(FetchProfile.Item.CONTENT_INFO)) {
1378 appendAtom("BODYSTRUCTURE");
1379 }
1380 if (profile.contains(IMAPFolder.FetchProfileItem.SIZE)) {
1381 appendAtom("RFC822.SIZE");
1382 }
1383
1384
1385
1386 if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS)) {
1387 appendAtom("BODY.PEEK[HEADER]");
1388 }
1389 else {
1390 String[] headers = profile.getHeaderNames();
1391
1392
1393 if (headers.length > 0) {
1394 appendAtom("BODY.PEEK[HEADER.FIELDS]");
1395 startList();
1396 for (int i = 0; i < headers.length; i++) {
1397 appendAtom(headers[i]);
1398 }
1399 endList();
1400 }
1401 }
1402
1403 endList();
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413 public void appendACL(ACL acl) {
1414 appendACL(acl, null);
1415 }
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425 public void appendACL(ACL acl, String modifier) {
1426 appendString(acl.getName());
1427 String rights = acl.getRights().toString();
1428
1429 if (modifier != null) {
1430 rights = modifier + rights;
1431 }
1432 appendString(rights);
1433 }
1434
1435
1436
1437
1438
1439
1440
1441 public void appendQuota(Quota quota) {
1442 appendString(quota.quotaRoot);
1443 startList();
1444 for (int i = 0; i < quota.resources.length; i++) {
1445 appendQuotaResource(quota.resources[i]);
1446 }
1447 endList();
1448 }
1449
1450
1451
1452
1453
1454
1455
1456 public void appendQuotaResource(Quota.Resource resource) {
1457 appendAtom(resource.name);
1458
1459 appendLong(resource.limit);
1460 }
1461 }
1462