View Javadoc

1   /*
2    * Copyright 2004-2010 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  
17  package org.seasar.cubby.internal.util;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.UnsupportedEncodingException;
21  import java.util.BitSet;
22  
23  /**
24   * URL ボディ部のエンコーダです。
25   * 
26   * @author baba
27   */
28  public class URLBodyEncoder {
29  
30  	protected static byte ESCAPE_CHAR = '%';
31  
32  	/**
33  	 * BitSet of www-form-url safe characters.
34  	 */
35  	protected static final BitSet WWW_FORM_URL = new BitSet(256);
36  
37  	// Static initializer for www_form_url
38  	static {
39  		// alpha characters
40  		for (int i = 'a'; i <= 'z'; i++) {
41  			WWW_FORM_URL.set(i);
42  		}
43  		for (int i = 'A'; i <= 'Z'; i++) {
44  			WWW_FORM_URL.set(i);
45  		}
46  		// numeric characters
47  		for (int i = '0'; i <= '9'; i++) {
48  			WWW_FORM_URL.set(i);
49  		}
50  		// special chars
51  		WWW_FORM_URL.set('-');
52  		WWW_FORM_URL.set('_');
53  		WWW_FORM_URL.set('.');
54  		WWW_FORM_URL.set('*');
55  		// blank to be replaced with +
56  		// WWW_FORM_URL.set(' ');
57  	}
58  
59  	/**
60  	 * Default constructor.
61  	 */
62  	private URLBodyEncoder() {
63  		super();
64  	}
65  
66  	/**
67  	 * Encodes an array of bytes into an array of URL safe 7-bit characters.
68  	 * Unsafe characters are escaped.
69  	 * 
70  	 * @param urlsafe
71  	 *            bitset of characters deemed URL safe
72  	 * @param bytes
73  	 *            array of bytes to convert to URL safe characters
74  	 * @return array of bytes containing URL safe characters
75  	 */
76  	public static final byte[] encodeUrl(BitSet urlsafe, final byte[] bytes) {
77  		if (bytes == null) {
78  			return null;
79  		}
80  		if (urlsafe == null) {
81  			urlsafe = WWW_FORM_URL;
82  		}
83  
84  		final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
85  		for (final byte b : bytes) {
86  			final int b1 = b;
87  			final int b2;
88  			if (b1 < 0) {
89  				b2 = b1 + 256;
90  			} else {
91  				b2 = b1;
92  			}
93  
94  			if (urlsafe.get(b2)) {
95  				buffer.write(b2);
96  			} else {
97  				buffer.write('%');
98  				final char hex1 = Character.toUpperCase(Character.forDigit(
99  						(b2 >> 4) & 0xF, 16));
100 				final char hex2 = Character.toUpperCase(Character.forDigit(
101 						b2 & 0xF, 16));
102 				buffer.write(hex1);
103 				buffer.write(hex2);
104 			}
105 		}
106 		return buffer.toByteArray();
107 	}
108 
109 	/**
110 	 * Encodes an array of bytes into an array of URL safe 7-bit characters.
111 	 * Unsafe characters are escaped.
112 	 * 
113 	 * @param bytes
114 	 *            array of bytes to convert to URL safe characters
115 	 * @return array of bytes containing URL safe characters
116 	 */
117 	public static byte[] encode(final byte[] bytes) {
118 		return encodeUrl(WWW_FORM_URL, bytes);
119 	}
120 
121 	/**
122 	 * Encodes a string into its URL safe form using the specified string
123 	 * charset. Unsafe characters are escaped.
124 	 * 
125 	 * @param pString
126 	 *            string to convert to a URL safe form
127 	 * @param charset
128 	 *            the charset for pString
129 	 * @return URL safe string
130 	 * @throws UnsupportedEncodingException
131 	 *             Thrown if charset is not supported
132 	 */
133 	public static String encode(final String pString, final String charset)
134 			throws UnsupportedEncodingException {
135 		if (pString == null) {
136 			return null;
137 		}
138 		return new String(encode(pString.getBytes(charset)), "US-ASCII");
139 	}
140 
141 }