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;
19
20 import java.io.BufferedReader;
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.OutputStream;
27 import java.io.UnsupportedEncodingException;
28 import java.util.Date;
29 import java.util.Enumeration;
30 import java.util.List;
31
32 import javax.activation.DataHandler;
33
34 import javax.mail.Address;
35 import javax.mail.FetchProfile;
36 import javax.mail.Flags;
37 import javax.mail.Folder;
38 import javax.mail.Header;
39 import javax.mail.IllegalWriteException;
40 import javax.mail.Message;
41 import javax.mail.MessagingException;
42 import javax.mail.MessageRemovedException;
43 import javax.mail.Session;
44 import javax.mail.Store;
45 import javax.mail.UIDFolder;
46 import javax.mail.event.MessageChangedEvent;
47
48 import javax.mail.internet.InternetAddress;
49 import javax.mail.internet.InternetHeaders;
50 import javax.mail.internet.MailDateFormat;
51 import javax.mail.internet.MimeMessage;
52 import javax.mail.internet.MimeUtility;
53
54 import org.apache.geronimo.javamail.store.imap.connection.IMAPBody;
55 import org.apache.geronimo.javamail.store.imap.connection.IMAPBodyStructure;
56 import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection;
57 import org.apache.geronimo.javamail.store.imap.connection.IMAPEnvelope;
58 import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchDataItem;
59 import org.apache.geronimo.javamail.store.imap.connection.IMAPFetchResponse;
60 import org.apache.geronimo.javamail.store.imap.connection.IMAPInternalDate;
61 import org.apache.geronimo.javamail.store.imap.connection.IMAPInternetHeader;
62 import org.apache.geronimo.javamail.store.imap.connection.IMAPMessageSize;
63 import org.apache.geronimo.javamail.store.imap.connection.IMAPUid;
64 import org.apache.geronimo.javamail.util.MailConnection;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public class IMAPMessage extends MimeMessage {
80
81 private static final byte[] CRLF = "\r\n".getBytes();
82
83
84 protected IMAPStore store;
85
86
87 protected int sequenceNumber;
88
89 protected long uid = -1;
90
91
92 protected String section;
93
94 protected IMAPEnvelope envelope;
95
96 protected IMAPBodyStructure bodyStructure;
97
98 protected Date receivedDate;
99
100
101 protected int size;
102
103 protected boolean allHeadersRetrieved = false;
104
105 static protected MailDateFormat dateFormat = new MailDateFormat();
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 IMAPMessage(IMAPFolder folder, IMAPStore store, int msgnum, int sequenceNumber) {
124 super(folder, msgnum);
125 this.sequenceNumber = sequenceNumber;
126 this.store = store;
127
128
129 flags = null;
130
131 headers = new InternetHeaders();
132 }
133
134
135
136
137
138
139
140
141 public void setExpunged(boolean value) {
142
143 super.setExpunged(value);
144
145
146 if (isExpunged()) {
147 sequenceNumber = -1;
148 }
149 }
150
151
152
153
154
155
156
157
158 public synchronized Flags getFlags() throws MessagingException {
159
160 loadFlags();
161 return super.getFlags();
162 }
163
164
165
166
167
168
169
170
171
172
173 public synchronized boolean isSet(Flags.Flag flag) throws MessagingException {
174
175 loadFlags();
176 return super.isSet(flag);
177 }
178
179
180
181
182
183
184
185
186
187 public synchronized void setFlags(Flags flag, boolean set) throws MessagingException {
188
189 checkValidity();
190
191
192
193
194
195
196 synchronized (folder) {
197 IMAPConnection connection = getConnection();
198
199 try {
200
201
202
203 flags = connection.setFlags(sequenceNumber, flag, set);
204 } finally {
205 releaseConnection(connection);
206 }
207 }
208 }
209
210
211
212
213
214
215
216
217
218
219
220 protected InputStream getContentStream() throws MessagingException {
221
222
223 if (content == null) {
224
225 checkValidity();
226
227 loadContent();
228 }
229
230
231 return super.getContentStream();
232 }
233
234
235
236
237
238
239
240
241
242
243 public void writeTo(OutputStream out) throws IOException, MessagingException {
244
245 if (content == null) {
246
247 checkValidity();
248
249 loadContent();
250 }
251
252 loadHeaders();
253
254 Enumeration e = headers.getAllHeaderLines();
255 while(e.hasMoreElements()) {
256 String line = (String)e.nextElement();
257 out.write(line.getBytes());
258 out.write(CRLF);
259 }
260 out.write(CRLF);
261 out.write(CRLF);
262 out.write(content);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 public Address[] getFrom() throws MessagingException {
282
283 loadEnvelope();
284
285 Address[] addresses = envelope.from;
286 if (addresses == null) {
287 return null;
288 }
289 return (Address[])addresses.clone();
290 }
291
292
293
294
295
296
297
298
299 public Address getSender() throws MessagingException {
300
301 loadEnvelope();
302
303 Address[] addresses = envelope.sender;
304 if (addresses == null) {
305 return null;
306 }
307
308 return addresses[0];
309 }
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325 public Address[] getRecipients(Message.RecipientType type) throws MessagingException {
326
327 loadEnvelope();
328 Address[] addresses = null;
329
330 if (type == Message.RecipientType.TO) {
331 addresses = envelope.to;
332 }
333 else if (type == Message.RecipientType.CC) {
334 addresses = envelope.cc;
335 }
336 else if (type == Message.RecipientType.BCC) {
337 addresses = envelope.bcc;
338 }
339 else {
340
341 return super.getRecipients(type);
342 }
343
344 if (addresses == null) {
345 return null;
346 }
347 return (Address[])addresses.clone();
348 }
349
350
351
352
353
354
355
356
357
358 public Address[] getReplyTo() throws MessagingException {
359
360 loadEnvelope();
361
362 Address[] addresses = envelope.replyTo;
363 if (addresses == null) {
364 return null;
365 }
366 return (Address[])addresses.clone();
367 }
368
369
370
371
372
373
374
375
376
377
378 public String getSubject() throws MessagingException {
379
380 loadEnvelope();
381
382 if (envelope.subject == null) {
383 return null;
384 }
385
386
387 try {
388 return MimeUtility.decodeText(envelope.subject);
389 } catch (UnsupportedEncodingException e) {
390 return envelope.subject;
391 }
392 }
393
394
395
396
397
398
399
400
401 public Date getSentDate() throws MessagingException {
402
403 loadEnvelope();
404
405 return envelope.date;
406 }
407
408
409
410
411
412
413
414
415 public Date getReceivedDate() throws MessagingException {
416 loadEnvelope();
417 return receivedDate;
418 }
419
420
421
422
423
424
425
426
427
428 public int getSize() throws MessagingException {
429
430
431 loadEnvelope();
432 return size;
433 }
434
435
436
437
438
439
440
441
442
443
444 public int getLineCount() throws MessagingException {
445 loadBodyStructure();
446 return bodyStructure.lines;
447 }
448
449
450
451
452
453
454
455
456 public String getInReplyTo() throws MessagingException {
457 loadEnvelope();
458 return envelope.inReplyTo;
459 }
460
461
462
463
464
465
466
467
468 public String getContentType() throws MessagingException {
469 loadBodyStructure();
470 return bodyStructure.mimeType.toString();
471 }
472
473
474
475
476
477
478
479
480
481
482
483 public boolean isMimeType(String type) throws MessagingException {
484 loadBodyStructure();
485 return bodyStructure.mimeType.match(type);
486 }
487
488
489
490
491
492
493
494
495
496 public String getDisposition() throws MessagingException {
497 loadBodyStructure();
498 if (bodyStructure.disposition != null) {
499 return bodyStructure.disposition.getDisposition();
500 }
501 return null;
502 }
503
504
505
506
507
508
509
510
511 public String getEncoding() throws MessagingException {
512 loadBodyStructure();
513 return bodyStructure.transferEncoding;
514 }
515
516
517
518
519
520
521
522
523 public String getContentID() throws MessagingException {
524 loadBodyStructure();
525 return bodyStructure.contentID;
526 }
527
528 public String getContentMD5() throws MessagingException {
529 loadBodyStructure();
530 return bodyStructure.md5Hash;
531 }
532
533
534 public String getDescription() throws MessagingException {
535 loadBodyStructure();
536
537 if (bodyStructure.contentDescription == null) {
538 return null;
539 }
540
541
542 try {
543 return MimeUtility.decodeText(bodyStructure.contentDescription);
544 } catch (UnsupportedEncodingException e) {
545 return bodyStructure.contentDescription;
546 }
547 }
548
549
550
551
552
553
554
555
556 public String[] getContentLanguage() throws MessagingException {
557 loadBodyStructure();
558
559 if (!bodyStructure.languages.isEmpty()) {
560 return (String[])bodyStructure.languages.toArray(new String[bodyStructure.languages.size()]);
561 }
562 return null;
563 }
564
565 public String getMessageID() throws MessagingException {
566 loadEnvelope();
567 return envelope.messageID;
568 }
569
570 public void setFrom(Address address) throws MessagingException {
571 throw new IllegalWriteException("IMAP messages are read-only");
572 }
573
574 public void addFrom(Address[] address) throws MessagingException {
575 throw new IllegalWriteException("IMAP messages are read-only");
576 }
577
578 public void setSender(Address address) throws MessagingException {
579 throw new IllegalWriteException("IMAP messages are read-only");
580 }
581
582 public void setRecipients(Message.RecipientType type, Address[] addresses) throws MessagingException {
583 throw new IllegalWriteException("IMAP messages are read-only");
584 }
585
586 public void setRecipients(Message.RecipientType type, String address) throws MessagingException {
587 throw new IllegalWriteException("IMAP messages are read-only");
588 }
589
590 public void addRecipients(Message.RecipientType type, Address[] address) throws MessagingException {
591 throw new IllegalWriteException("IMAP messages are read-only");
592 }
593
594 public void setReplyTo(Address[] address) throws MessagingException {
595 throw new IllegalWriteException("IMAP messages are read-only");
596 }
597
598 public void setSubject(String subject) throws MessagingException {
599 throw new IllegalWriteException("IMAP messages are read-only");
600 }
601
602 public void setSubject(String subject, String charset) throws MessagingException {
603 throw new IllegalWriteException("IMAP messages are read-only");
604 }
605
606 public void setSentDate(Date sent) throws MessagingException {
607 throw new IllegalWriteException("IMAP messages are read-only");
608 }
609
610 public void setDisposition(String disposition) throws MessagingException {
611 throw new IllegalWriteException("IMAP messages are read-only");
612 }
613
614 public void setContentID(String cid) throws MessagingException {
615 throw new IllegalWriteException("IMAP messages are read-only");
616 }
617
618 public void setContentMD5(String md5) throws MessagingException {
619 throw new IllegalWriteException("IMAP messages are read-only");
620 }
621
622 public void setDescription(String description) throws MessagingException {
623 throw new IllegalWriteException("IMAP messages are read-only");
624 }
625
626 public void setDescription(String description, String charset) throws MessagingException {
627 throw new IllegalWriteException("IMAP messages are read-only");
628 }
629
630 public void setContentLanguage(String[] languages) throws MessagingException {
631 throw new IllegalWriteException("IMAP messages are read-only");
632 }
633
634
635
636
637
638
639
640
641 public String[] getHeader(String name) throws MessagingException {
642 loadHeaders();
643 return headers.getHeader(name);
644 }
645
646 public String getHeader(String name, String delimiter) throws MessagingException {
647 loadHeaders();
648 return headers.getHeader(name, delimiter);
649 }
650
651 public Enumeration getAllHeaders() throws MessagingException {
652 loadHeaders();
653 return headers.getAllHeaders();
654 }
655
656 public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
657 loadHeaders();
658 return headers.getMatchingHeaders(names);
659 }
660
661 public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
662 loadHeaders();
663 return headers.getNonMatchingHeaders(names);
664 }
665
666 public Enumeration getAllHeaderLines() throws MessagingException {
667 loadHeaders();
668 return headers.getAllHeaderLines();
669 }
670
671 public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
672 loadHeaders();
673 return headers.getMatchingHeaderLines(names);
674 }
675
676 public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
677 loadHeaders();
678 return headers.getNonMatchingHeaderLines(names);
679 }
680
681
682
683 public void addHeader(String name, String value) throws MessagingException {
684 throw new IllegalWriteException("IMAP messages are read-only");
685 }
686
687 public void setHeader(String name, String value) throws MessagingException {
688 throw new IllegalWriteException("IMAP messages are read-only");
689 }
690
691
692 public void removeHeader(String name) throws MessagingException {
693 throw new IllegalWriteException("IMAP messages are read-only");
694 }
695
696 public void addHeaderLine(String line) throws MessagingException {
697 throw new IllegalWriteException("IMAP messages are read-only");
698 }
699
700
701
702
703 public void saveChanges() throws MessagingException {
704 throw new IllegalWriteException("IMAP messages are read-only");
705 }
706
707
708
709
710
711
712
713
714
715 protected void updateHeader(String header, InternetAddress[] addresses) throws MessagingException {
716 if (addresses != null) {
717 headers.addHeader(header, InternetAddress.toString(addresses));
718 }
719 }
720
721
722
723
724
725
726
727
728 protected void updateHeader(String header, Address address) throws MessagingException {
729 if (address != null) {
730 headers.setHeader(header, address.toString());
731 }
732 }
733
734
735
736
737
738
739
740
741 protected void updateHeader(String header, String value) throws MessagingException {
742 if (value != null) {
743 headers.setHeader(header, value);
744 }
745 }
746
747
748
749
750
751
752
753
754
755 public synchronized DataHandler getDataHandler() throws MessagingException {
756
757 checkValidity();
758 loadBodyStructure();
759 if (dh == null) {
760
761 if (bodyStructure.isMultipart()) {
762 dh = new DataHandler(new IMAPMultipartDataSource(this, this, section, bodyStructure));
763 return dh;
764 }
765 else if (bodyStructure.isAttachedMessage()) {
766 dh = new DataHandler(new IMAPAttachedMessage(this, section, bodyStructure.nestedEnvelope, bodyStructure.nestedBody),
767 bodyStructure.mimeType.toString());
768 return dh;
769 }
770 }
771
772
773 return super.getDataHandler();
774 }
775
776 public void setDataHandler(DataHandler content) throws MessagingException {
777 throw new IllegalWriteException("IMAP body parts are read-only");
778 }
779
780
781
782
783
784
785
786
787 public void updateHeaders(InputStream in) throws MessagingException {
788
789 headers = new InternetHeaders(in);
790 allHeadersRetrieved = true;
791 }
792
793
794
795
796
797
798 public void loadFlags() throws MessagingException {
799
800 checkValidity();
801
802 if (flags != null) {
803 return;
804 }
805
806
807
808
809
810 synchronized (folder) {
811 IMAPConnection connection = getConnection();
812
813 try {
814
815 flags = connection.fetchFlags(sequenceNumber);
816 } finally {
817 releaseConnection(connection);
818 }
819 }
820 }
821
822
823
824
825
826
827
828 protected synchronized void loadHeaders() throws MessagingException {
829
830 if (allHeadersRetrieved) {
831 return;
832 }
833
834
835 checkValidity();
836
837
838
839
840
841 synchronized (folder) {
842 IMAPConnection connection = getConnection();
843
844 try {
845
846 headers = connection.fetchHeaders(sequenceNumber, section);
847
848 allHeadersRetrieved = true;
849 } finally {
850 releaseConnection(connection);
851 }
852 }
853 }
854
855
856
857
858
859
860
861
862 protected synchronized void loadEnvelope() throws MessagingException {
863
864 if (envelope != null) {
865 return;
866 }
867
868
869 checkValidity();
870
871
872
873
874
875 synchronized (folder) {
876 IMAPConnection connection = getConnection();
877 try {
878
879 List fetches = connection.fetchEnvelope(sequenceNumber);
880
881
882
883 for (int i = 0; i < fetches.size(); i++) {
884
885
886 IMAPFetchResponse fetch = (IMAPFetchResponse)fetches.get(i);
887
888 updateMessageInformation(fetch);
889 }
890 } finally {
891 releaseConnection(connection);
892 }
893 }
894 }
895
896
897
898
899
900
901
902
903 protected synchronized void updateEnvelope(IMAPEnvelope envelope) throws MessagingException {
904
905 this.envelope = envelope;
906
907
908 updateHeader("From", envelope.from);
909 if (envelope.sender != null) {
910
911 updateHeader("Sender", envelope.sender[0]);
912 }
913 updateHeader("To", envelope.to);
914 updateHeader("Cc", envelope.cc);
915 updateHeader("Bcc", envelope.bcc);
916 updateHeader("Reply-To", envelope.replyTo);
917
918 updateHeader("Subject", envelope.subject);
919 updateHeader("Message-ID", envelope.messageID);
920 }
921
922
923
924
925
926
927
928 protected synchronized void loadBodyStructure() throws MessagingException {
929
930 if (bodyStructure != null) {
931 return;
932 }
933
934
935 checkValidity();
936
937
938
939
940
941 synchronized (folder) {
942 IMAPConnection connection = getConnection();
943 try {
944
945 bodyStructure = connection.fetchBodyStructure(sequenceNumber);
946
947 } finally {
948 releaseConnection(connection);
949 }
950
951
952
953 updateBodyStructure(bodyStructure);
954 }
955 }
956
957
958
959
960
961
962
963 protected synchronized void updateBodyStructure(IMAPBodyStructure structure) throws MessagingException {
964
965 bodyStructure = structure;
966
967
968
969 if (bodyStructure.lines != -1) {
970 updateHeader("Lines", Integer.toString(bodyStructure.lines));
971 }
972
973
974 if (bodyStructure.languages != null) {
975
976
977
978 if (bodyStructure.languages.size() == 1) {
979 updateHeader("Content-Language", (String)bodyStructure.languages.get(0));
980 }
981 else {
982 StringBuffer buf = new StringBuffer(bodyStructure.languages.size() * 20);
983 buf.append(bodyStructure.languages.get(0));
984 for (int i = 1; i < bodyStructure.languages.size(); i++) {
985 buf.append(',').append(bodyStructure.languages.get(i));
986 }
987 updateHeader("Content-Language", buf.toString());
988 }
989 }
990
991 updateHeader("Content-Type", bodyStructure.mimeType.toString());
992 if (bodyStructure.disposition != null) {
993 updateHeader("Content-Disposition", bodyStructure.disposition.toString());
994 }
995
996 updateHeader("Content-Transfer-Encoding", bodyStructure.transferEncoding);
997 updateHeader("Content-ID", bodyStructure.contentID);
998
999 updateHeader("Content-Description", bodyStructure.contentDescription);
1000 }
1001
1002
1003
1004
1005
1006
1007
1008 protected void loadContent() throws MessagingException {
1009
1010 if (content != null) {
1011 return;
1012 }
1013
1014
1015
1016
1017
1018
1019 synchronized (folder) {
1020 IMAPConnection connection = getConnection();
1021 try {
1022
1023 content = connection.fetchContent(getSequenceNumber(), section);
1024 } finally {
1025 releaseConnection(connection);
1026 }
1027 }
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 int getSequenceNumber() {
1038 return sequenceNumber;
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048 void setSequenceNumber(int s) {
1049 sequenceNumber = s;
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 long getUID() {
1059 return uid;
1060 }
1061
1062
1063
1064
1065
1066
1067 void setUID(long uid) {
1068 this.uid = uid;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080 protected IMAPConnection getConnection() throws MessagingException {
1081
1082 return ((IMAPFolder)folder).getMessageConnection();
1083 }
1084
1085
1086
1087
1088
1089
1090
1091 protected void releaseConnection(IMAPConnection connection) throws MessagingException {
1092
1093 ((IMAPFolder)folder).releaseMessageConnection(connection);
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 protected void checkValidity() throws MessagingException {
1105 checkValidity(false);
1106 }
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 protected void checkValidity(boolean update) throws MessagingException {
1117
1118
1119
1120
1121
1122 if (update) {
1123 synchronized (folder) {
1124
1125
1126
1127 IMAPConnection connection = getConnection();
1128
1129 try {
1130 connection.updateMailboxStatus();
1131 } finally {
1132
1133
1134 releaseConnection(connection);
1135 }
1136 }
1137 }
1138
1139
1140 if (isExpunged()) {
1141 throw new MessageRemovedException("Illegal opertion on a deleted message");
1142 }
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161 protected boolean evaluateFetch(FetchProfile profile) {
1162
1163
1164
1165
1166 if (profile.contains(UIDFolder.FetchProfileItem.UID) && uid == -1) {
1167 return true;
1168 }
1169 if (profile.contains(FetchProfile.Item.ENVELOPE) && envelope == null) {
1170 return true;
1171 }
1172 if (profile.contains(FetchProfile.Item.FLAGS) && flags == null) {
1173 return true;
1174 }
1175 if (profile.contains(FetchProfile.Item.CONTENT_INFO) && bodyStructure == null) {
1176 return true;
1177 }
1178
1179
1180 if (profile.contains(IMAPFolder.FetchProfileItem.HEADERS) && !allHeadersRetrieved) {
1181 return true;
1182 }
1183 if (profile.contains(IMAPFolder.FetchProfileItem.SIZE) && bodyStructure.bodySize < 0) {
1184 return true;
1185 }
1186
1187
1188
1189 String [] requestedHeaders = profile.getHeaderNames();
1190
1191
1192
1193 for (int i = 0; i < requestedHeaders.length; i++) {
1194 if (headers.getHeader(requestedHeaders[i]) == null) {
1195 return true;
1196 }
1197 }
1198
1199 return false;
1200 }
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 void updateMessageInformation(IMAPFetchResponse response) throws MessagingException {
1212
1213
1214 List items = response.getDataItems();
1215
1216 for (int i = 0; i < items.size(); i++) {
1217 IMAPFetchDataItem item = (IMAPFetchDataItem)items.get(i);
1218
1219 switch (item.getType()) {
1220
1221 case IMAPFetchDataItem.ENVELOPE:
1222
1223 updateEnvelope((IMAPEnvelope)item);
1224 break;
1225 case IMAPFetchDataItem.INTERNALDATE:
1226 receivedDate = ((IMAPInternalDate)item).getDate();;
1227 break;
1228 case IMAPFetchDataItem.SIZE:
1229 size = ((IMAPMessageSize)item).size;
1230 break;
1231 case IMAPFetchDataItem.UID:
1232 uid = ((IMAPUid)item).uid;
1233
1234 ((IMAPFolder)folder).addToUidCache(new Long(uid), this);
1235 break;
1236 case IMAPFetchDataItem.BODYSTRUCTURE:
1237 updateBodyStructure((IMAPBodyStructure)item);
1238 break;
1239
1240 case IMAPFetchDataItem.HEADER:
1241 {
1242
1243 IMAPInternetHeader h = (IMAPInternetHeader)item;
1244 if (h.isComplete()) {
1245
1246 this.headers = h.headers;
1247 allHeadersRetrieved = true;
1248 }
1249 else {
1250
1251
1252
1253 mergeHeaders(h.headers);
1254 }
1255 }
1256 default:
1257 }
1258 }
1259 }
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 protected synchronized void mergeHeaders(InternetHeaders newHeaders) {
1270
1271
1272
1273
1274
1275
1276
1277
1278 Enumeration e = headers.getAllHeaders();
1279
1280 while (e.hasMoreElements()) {
1281 Header header = (Header)e.nextElement();
1282
1283
1284
1285
1286
1287 if (newHeaders.getHeader(header.getName()) == null) {
1288
1289
1290 String name = header.getName();
1291 String[] a = headers.getHeader(name);
1292 for (int i = 0; i < a.length; i++) {
1293 newHeaders.addHeader(name, a[i]);
1294 }
1295 }
1296 }
1297
1298 headers = newHeaders;
1299 }
1300 }