001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.catalina.util;
018:
019: import java.io.ByteArrayOutputStream;
020: import java.io.IOException;
021: import java.io.OutputStreamWriter;
022: import java.util.BitSet;
023:
024: /**
025: *
026: * This class is very similar to the java.net.URLEncoder class.
027: *
028: * Unfortunately, with java.net.URLEncoder there is no way to specify to the
029: * java.net.URLEncoder which characters should NOT be encoded.
030: *
031: * This code was moved from DefaultServlet.java
032: *
033: * @author Craig R. McClanahan
034: * @author Remy Maucherat
035: */
036: public class URLEncoder {
037: protected static final char[] hexadecimal = { '0', '1', '2', '3',
038: '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
039:
040: //Array containing the safe characters set.
041: protected BitSet safeCharacters = new BitSet(256);
042:
043: public URLEncoder() {
044: for (char i = 'a'; i <= 'z'; i++) {
045: addSafeCharacter(i);
046: }
047: for (char i = 'A'; i <= 'Z'; i++) {
048: addSafeCharacter(i);
049: }
050: for (char i = '0'; i <= '9'; i++) {
051: addSafeCharacter(i);
052: }
053: }
054:
055: public void addSafeCharacter(char c) {
056: safeCharacters.set(c);
057: }
058:
059: public String encode(String path) {
060: int maxBytesPerChar = 10;
061: int caseDiff = ('a' - 'A');
062: StringBuffer rewrittenPath = new StringBuffer(path.length());
063: ByteArrayOutputStream buf = new ByteArrayOutputStream(
064: maxBytesPerChar);
065: OutputStreamWriter writer = null;
066: try {
067: writer = new OutputStreamWriter(buf, "UTF8");
068: } catch (Exception e) {
069: e.printStackTrace();
070: writer = new OutputStreamWriter(buf);
071: }
072:
073: for (int i = 0; i < path.length(); i++) {
074: int c = (int) path.charAt(i);
075: if (safeCharacters.get(c)) {
076: rewrittenPath.append((char) c);
077: } else {
078: // convert to external encoding before hex conversion
079: try {
080: writer.write((char) c);
081: writer.flush();
082: } catch (IOException e) {
083: buf.reset();
084: continue;
085: }
086: byte[] ba = buf.toByteArray();
087: for (int j = 0; j < ba.length; j++) {
088: // Converting each byte in the buffer
089: byte toEncode = ba[j];
090: rewrittenPath.append('%');
091: int low = (int) (toEncode & 0x0f);
092: int high = (int) ((toEncode & 0xf0) >> 4);
093: rewrittenPath.append(hexadecimal[high]);
094: rewrittenPath.append(hexadecimal[low]);
095: }
096: buf.reset();
097: }
098: }
099: return rewrittenPath.toString();
100: }
101: }
|