KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > mail > imap > protocol > BODYSTRUCTURE


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)BODYSTRUCTURE.java 1.17 05/08/29
24  *
25  * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package com.sun.mail.imap.protocol;
29
30 import java.util.Vector JavaDoc;
31 import javax.mail.internet.ParameterList JavaDoc;
32 import com.sun.mail.iap.*;
33
34 /**
35  * A BODYSTRUCTURE response.
36  *
37  * @version 1.17, 05/08/29
38  * @author John Mani
39  */

40
41 public class BODYSTRUCTURE implements Item {
42     
43     public static char [] name = {'B','O','D','Y','S','T','R','U','C','T','U','R','E'};
44     public int msgno;
45
46     public String JavaDoc type; // Type
47
public String JavaDoc subtype; // Subtype
48
public String JavaDoc encoding; // Encoding
49
public int lines = -1; // Size in lines
50
public int size = -1; // Size in bytes
51
public String JavaDoc disposition; // Disposition
52
public String JavaDoc id; // Content-ID
53
public String JavaDoc description; // Content-Description
54
public String JavaDoc md5; // MD-5 checksum
55
public String JavaDoc attachment; // Attachment name
56
public ParameterList JavaDoc cParams; // Body parameters
57
public ParameterList JavaDoc dParams; // Disposition parameters
58
public String JavaDoc[] language; // Language
59
public BODYSTRUCTURE[] bodies; // array of BODYSTRUCTURE objects
60
// for multipart & message/rfc822
61
public ENVELOPE envelope; // for message/rfc822
62

63     private static int SINGLE = 1;
64     private static int MULTI = 2;
65     private static int NESTED = 3;
66     private int processedType; // MULTI | SINGLE | NESTED
67

68     public BODYSTRUCTURE(FetchResponse r) throws ParsingException {
69     msgno = r.getNumber();
70
71     r.skipSpaces();
72
73     if (r.readByte() != '(')
74         throw new ParsingException(
75         "BODYSTRUCTURE parse error: missing ``('' at start");
76
77     if (r.peekByte() == '(') { // multipart
78
type = "multipart";
79         processedType = MULTI;
80         Vector JavaDoc v = new Vector JavaDoc(1);
81         int i = 1;
82         do {
83         v.addElement(new BODYSTRUCTURE(r));
84         /*
85          * Even though the IMAP spec says there can't be any spaces
86          * between parts, some servers erroneously put a space in
87          * here. In the spirit of "be liberal in what you accept",
88          * we skip it.
89          */

90         r.skipSpaces();
91         } while (r.peekByte() == '(');
92
93         // setup bodies.
94
bodies = new BODYSTRUCTURE[v.size()];
95         v.copyInto(bodies);
96
97         subtype = r.readString(); // subtype
98

99         if (r.readByte() == ')') // done
100
return;
101
102         // Else, we have extension data
103

104         // Body parameters
105
cParams = parseParameters(r);
106         if (r.readByte() == ')') // done
107
return;
108         
109         // Disposition
110
byte b = r.readByte();
111         if (b == '(') {
112         disposition = r.readString();
113         dParams = parseParameters(r);
114         if (r.readByte() != ')') // eat the end ')'
115
throw new ParsingException(
116             "BODYSTRUCTURE parse error: " +
117             "missing ``)'' at end of disposition in multipart");
118         } else if (b == 'N' || b == 'n') {
119         r.skip(2); // skip 'NIL'
120
} else {
121         throw new ParsingException(
122             "BODYSTRUCTURE parse error: " +
123             type + "/" + subtype + ": " +
124             "bad multipart disposition, b " + b);
125         }
126
127         // RFC3501 allows no body-fld-lang after body-fld-disp,
128
// even though RFC2060 required it
129
if ((b = r.readByte()) == ')')
130         return; // done
131

132         if (b != ' ')
133         throw new ParsingException(
134             "BODYSTRUCTURE parse error: " +
135             "missing space after disposition");
136
137         // Language
138
if (r.peekByte() == '(') // a list follows
139
language = r.readStringList();
140         else {
141         String JavaDoc l = r.readString();
142         if (l != null) {
143             String JavaDoc[] la = { l };
144             language = la;
145         }
146         }
147
148         // RFC3501 defines an optional "body location" next,
149
// but for now we ignore it along with other extensions.
150

151         // Throw away any further extension data
152
while (r.readByte() == ' ')
153         parseBodyExtension(r);
154     }
155     else { // Single part
156
type = r.readString();
157         processedType = SINGLE;
158         subtype = r.readString();
159
160         // SIMS 4.0 returns NIL for a Content-Type of "binary", fix it here
161
if (type == null) {
162         type = "application";
163         subtype = "octet-stream";
164         }
165         cParams = parseParameters(r);
166         id = r.readString();
167         description = r.readString();
168         encoding = r.readString();
169         size = r.readNumber();
170         if (size < 0)
171         throw new ParsingException(
172                 "BODYSTRUCTURE parse error: bad ``size'' element");
173
174         // "text/*" & "message/rfc822" types have additional data ..
175
if (type.equalsIgnoreCase("text")) {
176         lines = r.readNumber();
177         if (lines < 0)
178             throw new ParsingException(
179                 "BODYSTRUCTURE parse error: bad ``lines'' element");
180         } else if (type.equalsIgnoreCase("message") &&
181              subtype.equalsIgnoreCase("rfc822")) {
182         // Nested message
183
processedType = NESTED;
184         envelope = new ENVELOPE(r);
185         BODYSTRUCTURE[] bs = { new BODYSTRUCTURE(r) };
186         bodies = bs;
187         lines = r.readNumber();
188         if (lines < 0)
189             throw new ParsingException(
190                 "BODYSTRUCTURE parse error: bad ``lines'' element");
191         } else {
192         // Detect common error of including lines element on other types
193
r.skipSpaces();
194         byte bn = r.peekByte();
195         if (Character.isDigit((char)bn)) // number
196
throw new ParsingException(
197                 "BODYSTRUCTURE parse error: server erroneously " +
198                 "included ``lines'' element with type " +
199                 type + "/" + subtype);
200         }
201
202         if (r.peekByte() == ')') {
203         r.readByte();
204         return; // done
205
}
206
207         // Optional extension data
208

209         // MD5
210
md5 = r.readString();
211         if (r.readByte() == ')')
212         return; // done
213

214         // Disposition
215
byte b = r.readByte();
216         if (b == '(') {
217         disposition = r.readString();
218         dParams = parseParameters(r);
219         if (r.readByte() != ')') // eat the end ')'
220
throw new ParsingException(
221             "BODYSTRUCTURE parse error: " +
222             "missing ``)'' at end of disposition");
223         } else if (b == 'N' || b == 'n') {
224         r.skip(2); // skip 'NIL'
225
} else {
226         throw new ParsingException(
227             "BODYSTRUCTURE parse error: " +
228             type + "/" + subtype + ": " +
229             "bad single part disposition, b " + b);
230         }
231
232         if (r.readByte() == ')')
233         return; // done
234

235         // Language
236
if (r.peekByte() == '(') // a list follows
237
language = r.readStringList();
238         else { // protocol is unnessarily complex here
239
String JavaDoc l = r.readString();
240         if (l != null) {
241             String JavaDoc[] la = { l };
242             language = la;
243         }
244         }
245
246         // RFC3501 defines an optional "body location" next,
247
// but for now we ignore it along with other extensions.
248

249         // Throw away any further extension data
250
while (r.readByte() == ' ')
251         parseBodyExtension(r);
252     }
253     }
254
255     public boolean isMulti() {
256     return processedType == MULTI;
257     }
258
259     public boolean isSingle() {
260     return processedType == SINGLE;
261     }
262
263     public boolean isNested() {
264     return processedType == NESTED;
265     }
266
267     private ParameterList JavaDoc parseParameters(Response r)
268             throws ParsingException {
269     r.skipSpaces();
270
271     ParameterList JavaDoc list = null;
272     byte b = r.readByte();
273     if (b == '(') {
274         list = new ParameterList JavaDoc();
275         do {
276         String JavaDoc name = r.readString();
277         String JavaDoc value = r.readString();
278         list.set(name, value);
279         } while (r.readByte() != ')');
280     } else if (b == 'N' || b == 'n')
281         r.skip(2);
282     else
283         throw new ParsingException("Parameter list parse error");
284     
285     return list;
286     }
287
288     private void parseBodyExtension(Response r) throws ParsingException {
289     r.skipSpaces();
290
291     byte b = r.peekByte();
292     if (b == '(') {
293         r.skip(1); // skip '('
294
do {
295         parseBodyExtension(r);
296         } while (r.readByte() != ')');
297     } else if (Character.isDigit((char)b)) // number
298
r.readNumber();
299     else // nstring
300
r.readString();
301     }
302 }
303
Popular Tags