KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > util > URLUtil


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/util/org/apache/util/URLUtil.java,v 1.8 2004/07/28 09:33:13 ib Exp $
3  * $Revision: 1.8 $
4  * $Date: 2004/07/28 09:33:13 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24
25 package org.apache.util;
26
27 import java.io.ByteArrayOutputStream JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.OutputStreamWriter JavaDoc;
30 import java.io.UnsupportedEncodingException JavaDoc;
31 import java.text.SimpleDateFormat JavaDoc;
32 import java.util.BitSet JavaDoc;
33 import java.util.TimeZone JavaDoc;
34
35
36 /**
37  * General purpose request parsing and encoding utility methods.
38  *
39  * @version $Revision: 1.8 $ $Date: 2004/07/28 09:33:13 $
40  */

41
42 public final class URLUtil {
43
44
45     // -------------------------------------------------------------- Variables
46

47     
48     /**
49      * The DateFormat to use for generating readable dates in cookies.
50      */

51     private static SimpleDateFormat JavaDoc format =
52         new SimpleDateFormat JavaDoc(" EEEE, dd-MMM-yy kk:mm:ss zz");
53     
54     
55     /**
56      * Array containing the safe characters set.
57      */

58     protected static BitSet JavaDoc safeCharacters;
59     
60     
61     protected static final char[] hexadecimal =
62     {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
63      'A', 'B', 'C', 'D', 'E', 'F'};
64     
65     
66     // ----------------------------------------------------- Static Initializer
67

68     
69     static {
70         
71         format.setTimeZone(TimeZone.getTimeZone("GMT"));
72         
73         safeCharacters = new BitSet JavaDoc(256);
74         int i;
75         for (i = 'a'; i <= 'z'; i++) {
76             safeCharacters.set(i);
77         }
78         for (i = 'A'; i <= 'Z'; i++) {
79             safeCharacters.set(i);
80         }
81         for (i = '0'; i <= '9'; i++) {
82             safeCharacters.set(i);
83         }
84         safeCharacters.set('-');
85         safeCharacters.set('_');
86         safeCharacters.set('.');
87         safeCharacters.set('*');
88         safeCharacters.set('/');
89         
90     }
91     
92     
93     // --------------------------------------------------------- Public Methods
94

95     
96     /**
97      * Decode and return the specified URL-encoded String.
98      * When the byte array is converted to a string, the system default
99      * character encoding is used... This may be different than some other
100      * servers.
101      *
102      * @param str The url-encoded string
103      *
104      * @exception IllegalArgumentException if a '%' character is not followed
105      * by a valid 2-digit hexadecimal number
106      */

107     public static String JavaDoc URLDecode(String JavaDoc str) {
108         
109         return URLDecode(str, null);
110         
111     }
112
113
114     /**
115      * Decode and return the specified URL-encoded String.
116      *
117      * @param str The url-encoded string
118      * @param enc The encoding to use; if null, the default encoding is used
119      * @exception IllegalArgumentException if a '%' character is not followed
120      * by a valid 2-digit hexadecimal number
121      */

122     public static String JavaDoc URLDecode(String JavaDoc str, String JavaDoc enc) {
123         
124         if (str == null)
125             return (null);
126         
127         // FIXME: replace all byte[] by char[]
128
byte[] bytes;
129         if (enc==null) {
130             bytes=str.getBytes();
131         }
132         else {
133             try {
134                 bytes=str.getBytes(enc);
135             }
136             catch (UnsupportedEncodingException JavaDoc ex) {
137                 bytes=str.getBytes();
138             }
139         }
140         
141         return URLDecode(bytes, enc);
142     }
143
144
145     /**
146      * Decode and return the specified URL-encoded byte array.
147      *
148      * @param bytes The url-encoded byte array
149      * @exception IllegalArgumentException if a '%' character is not followed
150      * by a valid 2-digit hexadecimal number
151      */

152     public static String JavaDoc URLDecode(byte[] bytes) {
153         return URLDecode(bytes, null);
154     }
155
156
157     /**
158      * Decode and return the specified URL-encoded byte array.
159      *
160      * @param bytes The url-encoded byte array
161      * @param enc The encoding to use; if null, the default encoding is used
162      * @exception IllegalArgumentException if a '%' character is not followed
163      * by a valid 2-digit hexadecimal number
164      */

165     public static String JavaDoc URLDecode(byte[] bytes, String JavaDoc enc) {
166         
167         if (bytes == null)
168             return (null);
169         
170         int len = bytes.length;
171         int ix = 0;
172         int ox = 0;
173         while (ix < len) {
174             byte b = bytes[ix++]; // Get byte to test
175
if (b == '%') {
176                 b = (byte) ((convertHexDigit(bytes[ix++]) << 4)
177                             + convertHexDigit(bytes[ix++]));
178             }
179             if (b == '+') {
180                 b = (byte)' ';
181             }
182
183             bytes[ox++] = b;
184         }
185         if (enc != null) {
186             try {
187                 return new String JavaDoc(bytes, 0, ox, enc);
188             } catch (Exception JavaDoc e) {
189                 e.printStackTrace();
190             }
191         }
192         return new String JavaDoc(bytes, 0, ox);
193         
194     }
195
196
197     /**
198      * Convert a byte character value to hexidecimal digit value.
199      *
200      * @param b the character value byte
201      */

202     private static byte convertHexDigit( byte b ) {
203         if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
204         if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
205         if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
206         return 0;
207     }
208
209
210     /**
211      * URL rewriter.
212      *
213      * @param path Path which has to be rewiten
214      */

215     public static String JavaDoc URLEncode(String JavaDoc path, String JavaDoc enc) {
216
217         /**
218          * Note: This code portion is very similar to URLEncoder.encode.
219          * Unfortunately, there is no way to specify to the URLEncoder which
220          * characters should be encoded. Here, ' ' should be encoded as "%20"
221          * and '/' shouldn't be encoded.
222          */

223
224         int maxBytesPerChar = 10;
225         StringBuffer JavaDoc rewrittenPath = new StringBuffer JavaDoc(path.length());
226         ByteArrayOutputStream JavaDoc buf = new ByteArrayOutputStream JavaDoc(maxBytesPerChar);
227         OutputStreamWriter JavaDoc writer = null;
228         try {
229             // FIXME: Use the same encoding as the one specified above
230
writer = new OutputStreamWriter JavaDoc(buf, enc);
231         } catch (Exception JavaDoc e) {
232             e.printStackTrace();
233             writer = new OutputStreamWriter JavaDoc(buf);
234         }
235
236         for (int i = 0; i < path.length(); i++) {
237             int c = (int) path.charAt(i);
238             if (safeCharacters.get(c)) {
239                 rewrittenPath.append((char)c);
240             } else {
241                 // convert to external encoding before hex conversion
242
try {
243                     writer.write(c);
244                     writer.flush();
245                 } catch(IOException JavaDoc e) {
246                     buf.reset();
247                     continue;
248                 }
249                 byte[] ba = buf.toByteArray();
250                 for (int j = 0; j < ba.length; j++) {
251                     // Converting each byte in the buffer
252
byte toEncode = ba[j];
253                     rewrittenPath.append('%');
254                     int low = (int) (toEncode & 0x0f);
255                     int high = (int) ((toEncode & 0xf0) >> 4);
256                     rewrittenPath.append(hexadecimal[high]);
257                     rewrittenPath.append(hexadecimal[low]);
258                 }
259                 buf.reset();
260             }
261         }
262
263         return rewrittenPath.toString();
264
265     }
266     
267     
268 }
269
270
271
Popular Tags