KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > mail > iap > Argument


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  * @(#)Argument.java 1.10 05/08/29
24  *
25  * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28 package com.sun.mail.iap;
29
30 import java.util.Vector JavaDoc;
31 import java.io.*;
32 import com.sun.mail.util.*;
33
34 /**
35  * @version 1.10, 05/08/29
36  * @author John Mani
37  */

38
39 public class Argument {
40     protected Vector JavaDoc items;
41
42     /**
43      * Constructor
44      */

45     public Argument() {
46     items = new Vector JavaDoc(1);
47     }
48
49     /**
50      * append the given Argument to this Argument. All items
51      * from the source argument are copied into this destination
52      * argument.
53      */

54     public void append(Argument arg) {
55     items.ensureCapacity(items.size() + arg.items.size());
56     for (int i=0; i < arg.items.size(); i++)
57         items.addElement(arg.items.elementAt(i));
58     }
59
60     /**
61      * Write out given string as an ASTRING, depending on the type
62      * of the characters inside the string. The string should
63      * contain only ASCII characters. <p>
64      *
65      * XXX: Hmm .. this should really be called writeASCII()
66      *
67      * @param s String to write out
68      */

69     public void writeString(String JavaDoc s) {
70     items.addElement(new AString(ASCIIUtility.getBytes(s)));
71     }
72
73     /**
74      * Convert the given string into bytes in the specified
75      * charset, and write the bytes out as an ASTRING
76      */

77     public void writeString(String JavaDoc s, String JavaDoc charset)
78         throws UnsupportedEncodingException {
79     if (charset == null) // convenience
80
writeString(s);
81     else
82         items.addElement(new AString(s.getBytes(charset)));
83     }
84
85     /**
86      * Write out given byte[] as a Literal.
87      * @param b byte[] to write out
88      */

89     public void writeBytes(byte[] b) {
90     items.addElement(b);
91     }
92
93     /**
94      * Write out given ByteArrayOutputStream as a Literal.
95      * @param b ByteArrayOutputStream to be written out.
96      */

97     public void writeBytes(ByteArrayOutputStream b) {
98     items.addElement(b);
99     }
100
101     /**
102      * Write out given data as a literal.
103      * @param b Literal representing data to be written out.
104      */

105     public void writeBytes(Literal b) {
106     items.addElement(b);
107     }
108
109     /**
110      * Write out given string as an Atom. Note that an Atom can contain only
111      * certain US-ASCII characters. No validation is done on the characters
112      * in the string.
113      * @param s String
114      */

115     public void writeAtom(String JavaDoc s) {
116     items.addElement(new Atom(s));
117     }
118
119     /**
120      * Write out number.
121      * @param i number
122      */

123     public void writeNumber(int i) {
124     items.addElement(new Integer JavaDoc(i));
125     }
126
127     /**
128      * Write out number.
129      * @param i number
130      */

131     public void writeNumber(long i) {
132     items.addElement(new Long JavaDoc(i));
133     }
134
135     /**
136      * Write out as parenthesised list.
137      * @param s statement
138      */

139     public void writeArgument(Argument c) {
140     items.addElement(c);
141     }
142
143     /*
144      * Write out all the buffered items into the output stream.
145      */

146     public void write(Protocol protocol)
147         throws IOException, ProtocolException {
148     int size = items != null ? items.size() : 0;
149     DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
150
151     for (int i=0; i < size; i++) {
152         if (i > 0) // write delimiter if not the first item
153
os.write(' ');
154
155         Object JavaDoc o = items.elementAt(i);
156         if (o instanceof Atom) {
157         os.writeBytes(((Atom)o).string);
158         } else if (o instanceof Number JavaDoc) {
159         os.writeBytes(((Number JavaDoc)o).toString());
160         } else if (o instanceof AString) {
161         astring(((AString)o).bytes, protocol);
162         } else if (o instanceof byte[]) {
163         literal((byte[])o, protocol);
164         } else if (o instanceof ByteArrayOutputStream) {
165         literal((ByteArrayOutputStream)o, protocol);
166         } else if (o instanceof Literal) {
167         literal((Literal)o, protocol);
168         } else if (o instanceof Argument) {
169         os.write('('); // open parans
170
((Argument)o).write(protocol);
171         os.write(')'); // close parans
172
}
173     }
174     }
175
176     /**
177      * Write out given String as either an Atom, QuotedString or Literal
178      */

179     private void astring(byte[] bytes, Protocol protocol)
180             throws IOException, ProtocolException {
181     DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
182     int len = bytes.length;
183
184     // If length is greater than 1024 bytes, send as literal
185
if (len > 1024) {
186         literal(bytes, protocol);
187         return;
188     }
189
190         // if 0 length, send as quoted-string
191
boolean quote = len == 0 ? true: false;
192     boolean escape = false;
193     
194     byte b;
195     for (int i = 0; i < len; i++) {
196         b = bytes[i];
197         if (b == '\0' || b == '\r' || b == '\n' || ((b & 0xff) > 0177)) {
198         // NUL, CR or LF means the bytes need to be sent as literals
199
literal(bytes, protocol);
200         return;
201         }
202         if (b == '*' || b == '%' || b == '(' || b == ')' || b == '{' ||
203         b == '"' || b == '\\' || ((b & 0xff) <= ' ')) {
204         quote = true;
205         if (b == '"' || b == '\\') // need to escape these characters
206
escape = true;
207         }
208     }
209
210     if (quote) // start quote
211
os.write('"');
212
213         if (escape) {
214             // already quoted
215
for (int i = 0; i < len; i++) {
216                 b = bytes[i];
217                 if (b == '"' || b == '\\')
218                     os.write('\\');
219                 os.write(b);
220             }
221         } else
222             os.write(bytes);
223  
224
225     if (quote) // end quote
226
os.write('"');
227     }
228
229     /**
230      * Write out given byte[] as a literal
231      */

232     private void literal(byte[] b, Protocol protocol)
233             throws IOException, ProtocolException {
234     startLiteral(protocol, b.length).write(b);
235     }
236
237     /**
238      * Write out given ByteArrayOutputStream as a literal.
239      */

240     private void literal(ByteArrayOutputStream b, Protocol protocol)
241             throws IOException, ProtocolException {
242     b.writeTo(startLiteral(protocol, b.size()));
243     }
244
245     /**
246      * Write out given Literal as a literal.
247      */

248     private void literal(Literal b, Protocol protocol)
249             throws IOException, ProtocolException {
250     b.writeTo(startLiteral(protocol, b.size()));
251     }
252
253     private OutputStream startLiteral(Protocol protocol, int size)
254             throws IOException, ProtocolException {
255     DataOutputStream os = (DataOutputStream)protocol.getOutputStream();
256     boolean nonSync = protocol.supportsNonSyncLiterals();
257
258     os.write('{');
259     os.writeBytes(Integer.toString(size));
260     if (nonSync) // server supports non-sync literals
261
os.writeBytes("+}\r\n");
262     else
263         os.writeBytes("}\r\n");
264     os.flush();
265
266     // If we are using synchronized literals, wait for the server's
267
// continuation signal
268
if (!nonSync) {
269         for (; ;) {
270         Response r = protocol.readResponse();
271         if (r.isContinuation())
272             break;
273         if (r.isTagged())
274             throw new LiteralException(r);
275         // XXX - throw away untagged responses;
276
// violates IMAP spec, hope no servers do this
277
}
278     }
279     return os;
280     }
281 }
282
283 class Atom {
284     String JavaDoc string;
285
286     Atom(String JavaDoc s) {
287     string = s;
288     }
289 }
290
291 class AString {
292     byte[] bytes;
293
294     AString(byte[] b) {
295     bytes = b;
296     }
297 }
298
Popular Tags