KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > util > QuotedStringTokenizer


1 // ========================================================================
2
// $Id: QuotedStringTokenizer.java,v 1.4 2004/05/09 20:33:04 gregwilkins Exp $
3
// Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.util;
17
18 import java.util.NoSuchElementException JavaDoc;
19 import java.util.StringTokenizer JavaDoc;
20
21 /* ------------------------------------------------------------ */
22 /** StringTokenizer with Quoting support.
23  *
24  * This class is a copy of the java.util.StringTokenizer API and
25  * the behaviour is the same, except that single and doulbe quoted
26  * string values are recognized.
27  * Delimiters within quotes are not considered delimiters.
28  * Quotes can be escaped with '\'.
29  *
30  * @see java.util.StringTokenizer
31  * @version $Id: QuotedStringTokenizer.java,v 1.4 2004/05/09 20:33:04 gregwilkins Exp $
32  * @author Greg Wilkins (gregw)
33  */

34 public class QuotedStringTokenizer
35     extends StringTokenizer JavaDoc
36 {
37     private final static String JavaDoc __delim="\t\n\r";
38     private String JavaDoc _string;
39     private String JavaDoc _delim = __delim;
40     private boolean _returnQuotes=false;
41     private boolean _returnTokens=false;
42     private StringBuffer JavaDoc _token;
43     private boolean _hasToken=false;
44     private int _i=0;
45     private int _lastStart=0;
46     
47     /* ------------------------------------------------------------ */
48     public QuotedStringTokenizer(String JavaDoc str,
49                                  String JavaDoc delim,
50                                  boolean returnTokens,
51                                  boolean returnQuotes)
52     {
53         super("");
54         _string=str;
55         if (delim!=null)
56             _delim=delim;
57         _returnTokens=returnTokens;
58         _returnQuotes=returnQuotes;
59         
60         if (_delim.indexOf('\'')>=0 ||
61             _delim.indexOf('"')>=0)
62             throw new Error JavaDoc("Can't use quotes as delimiters: "+_delim);
63         
64         _token=new StringBuffer JavaDoc(_string.length()>1024?512:_string.length()/2);
65     }
66
67     /* ------------------------------------------------------------ */
68     public QuotedStringTokenizer(String JavaDoc str,
69                                  String JavaDoc delim,
70                                  boolean returnTokens)
71     {
72         this(str,delim,returnTokens,false);
73     }
74     
75     /* ------------------------------------------------------------ */
76     public QuotedStringTokenizer(String JavaDoc str,
77                                  String JavaDoc delim)
78     {
79         this(str,delim,false,false);
80     }
81
82     /* ------------------------------------------------------------ */
83     public QuotedStringTokenizer(String JavaDoc str)
84     {
85         this(str,null,false,false);
86     }
87
88     /* ------------------------------------------------------------ */
89     public boolean hasMoreTokens()
90     {
91         // Already found a token
92
if (_hasToken)
93             return true;
94         
95         _lastStart=_i;
96         
97         int state=0;
98         boolean escape=false;
99         while (_i<_string.length())
100         {
101             char c=_string.charAt(_i++);
102             
103             switch (state)
104             {
105               case 0: // Start
106
if(_delim.indexOf(c)>=0)
107                   {
108                       if (_returnTokens)
109                       {
110                           _token.append(c);
111                           return _hasToken=true;
112                       }
113                   }
114                   else if (c=='\'')
115                   {
116                       if (_returnQuotes)
117                           _token.append(c);
118                       state=2;
119                   }
120                   else if (c=='\"')
121                   {
122                       if (_returnQuotes)
123                           _token.append(c);
124                       state=3;
125                   }
126                   else
127                   {
128                       _token.append(c);
129                       _hasToken=true;
130                       state=1;
131                   }
132                   continue;
133                   
134               case 1: // Token
135
_hasToken=true;
136                   if(_delim.indexOf(c)>=0)
137                   {
138                       if (_returnTokens)
139                           _i--;
140                       return _hasToken;
141                   }
142                   else if (c=='\'')
143                   {
144                       if (_returnQuotes)
145                           _token.append(c);
146                       state=2;
147                   }
148                   else if (c=='\"')
149                   {
150                       if (_returnQuotes)
151                           _token.append(c);
152                       state=3;
153                   }
154                   else
155                       _token.append(c);
156                   continue;
157
158                   
159               case 2: // Single Quote
160
_hasToken=true;
161                   if (escape)
162                   {
163                       escape=false;
164                       _token.append(c);
165                   }
166                   else if (c=='\'')
167                   {
168                       if (_returnQuotes)
169                           _token.append(c);
170                       state=1;
171                   }
172                   else if (c=='\\')
173                   {
174                       if (_returnQuotes)
175                           _token.append(c);
176                       escape=true;
177                   }
178                   else
179                       _token.append(c);
180                   continue;
181
182                   
183               case 3: // Double Quote
184
_hasToken=true;
185                   if (escape)
186                   {
187                       escape=false;
188                       _token.append(c);
189                   }
190                   else if (c=='\"')
191                   {
192                       if (_returnQuotes)
193                           _token.append(c);
194                       state=1;
195                   }
196                   else if (c=='\\')
197                   {
198                       if (_returnQuotes)
199                           _token.append(c);
200                       escape=true;
201                   }
202                   else
203                       _token.append(c);
204                   continue;
205             }
206         }
207
208         return _hasToken;
209     }
210
211     /* ------------------------------------------------------------ */
212     public String JavaDoc nextToken()
213         throws NoSuchElementException JavaDoc
214     {
215         if (!hasMoreTokens() || _token==null)
216             throw new NoSuchElementException JavaDoc();
217         String JavaDoc t=_token.toString();
218         _token.setLength(0);
219         _hasToken=false;
220         return t;
221     }
222
223     /* ------------------------------------------------------------ */
224     public String JavaDoc nextToken(String JavaDoc delim)
225         throws NoSuchElementException JavaDoc
226     {
227         _delim=delim;
228         _i=_lastStart;
229         _token.setLength(0);
230         _hasToken=false;
231         return nextToken();
232     }
233
234     /* ------------------------------------------------------------ */
235     public boolean hasMoreElements()
236     {
237         return hasMoreTokens();
238     }
239
240     /* ------------------------------------------------------------ */
241     public Object JavaDoc nextElement()
242         throws NoSuchElementException JavaDoc
243     {
244         return nextToken();
245     }
246
247     /* ------------------------------------------------------------ */
248     /** Not implemented.
249      */

250     public int countTokens()
251     {
252         return -1;
253     }
254
255     
256     /* ------------------------------------------------------------ */
257     /** Quote a string.
258      * The string is quoted only if quoting is required due to
259      * embeded delimiters, quote characters or the
260      * empty string.
261      * @param s The string to quote.
262      * @return quoted string
263      */

264     public static String JavaDoc quote(String JavaDoc s, String JavaDoc delim)
265     {
266         if (s==null)
267             return null;
268         if (s.length()==0)
269             return "\"\"";
270
271         
272         for (int i=0;i<s.length();i++)
273         {
274             char c = s.charAt(i);
275             if (c=='"' ||
276                 c=='\\' ||
277                 c=='\'' ||
278                 delim.indexOf(c)>=0)
279             {
280                 StringBuffer JavaDoc b=new StringBuffer JavaDoc(s.length()+8);
281                 quote(b,s);
282                 return b.toString();
283             }
284         }
285         
286         return s;
287     }
288
289     /* ------------------------------------------------------------ */
290     /** Quote a string into a StringBuffer.
291      * @param buf The StringBuffer
292      * @param s The String to quote.
293      */

294     public static void quote(StringBuffer JavaDoc buf, String JavaDoc s)
295     {
296         synchronized(buf)
297         {
298             buf.append('"');
299             for (int i=0;i<s.length();i++)
300             {
301                 char c = s.charAt(i);
302                 if (c=='"')
303                 {
304                     buf.append("\\\"");
305                     continue;
306                 }
307                 if (c=='\\')
308                 {
309                     buf.append("\\\\");
310                     continue;
311                 }
312                 buf.append(c);
313                 continue;
314             }
315             buf.append('"');
316         }
317     }
318
319     /* ------------------------------------------------------------ */
320     /** Unquote a string.
321      * @param s The string to unquote.
322      * @return quoted string
323      */

324     public static String JavaDoc unquote(String JavaDoc s)
325     {
326         if (s==null)
327             return null;
328         if (s.length()<2)
329             return s;
330
331         char first=s.charAt(0);
332         char last=s.charAt(s.length()-1);
333         if (first!=last || (first!='"' && first!='\''))
334             return s;
335         
336         StringBuffer JavaDoc b=new StringBuffer JavaDoc(s.length()-2);
337         synchronized(b)
338         {
339             boolean quote=false;
340             for (int i=1;i<s.length()-1;i++)
341             {
342                 char c = s.charAt(i);
343
344                 if (c=='\\' && !quote)
345                 {
346                     quote=true;
347                     continue;
348                 }
349                 quote=false;
350                 b.append(c);
351             }
352             
353             return b.toString();
354         }
355     }
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
Popular Tags