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.camel.util;
018
019 import java.io.UnsupportedEncodingException;
020 import java.util.BitSet;
021
022 import org.apache.commons.logging.Log;
023 import org.apache.commons.logging.LogFactory;
024
025 /**
026 * Encoder for unsafe URI characters.
027 */
028 public final class UnsafeUriCharactersEncoder {
029 private static BitSet unsafeCharacters;
030 private static final transient Log LOG = LogFactory.getLog(UnsafeUriCharactersEncoder.class);
031 private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
032 'D', 'E', 'F'};
033
034 static {
035 unsafeCharacters = new BitSet(256);
036 unsafeCharacters.set(' ');
037 unsafeCharacters.set('"');
038 unsafeCharacters.set('<');
039 unsafeCharacters.set('>');
040 unsafeCharacters.set('#');
041 unsafeCharacters.set('%');
042 unsafeCharacters.set('{');
043 unsafeCharacters.set('}');
044 unsafeCharacters.set('|');
045 unsafeCharacters.set('\\');
046 unsafeCharacters.set('^');
047 unsafeCharacters.set('~');
048 unsafeCharacters.set('[');
049 unsafeCharacters.set(']');
050 unsafeCharacters.set('`');
051 }
052
053 private UnsafeUriCharactersEncoder() {
054 // util class
055 }
056
057 public static String encode(String s) {
058 int n = s.length();
059 if (n == 0) {
060 return s;
061 }
062
063 try {
064 // First check whether we actually need to encode
065 byte[] bytes = s.getBytes("UTF8");
066 for (int i = 0;;) {
067 if (unsafeCharacters.get(bytes[i])) {
068 break;
069 }
070 if (++i >= bytes.length) {
071 return s;
072 }
073 }
074
075 // okay there are some unsafe characters so we do need to encode
076 StringBuffer sb = new StringBuffer();
077 for (byte b : bytes) {
078 if (unsafeCharacters.get(b)) {
079 appendEscape(sb, b);
080 } else {
081 sb.append((char)b);
082 }
083 }
084 return sb.toString();
085 } catch (UnsupportedEncodingException e) {
086 LOG.error("Can't encoding the uri: ", e);
087 return null;
088 }
089 }
090
091 private static void appendEscape(StringBuffer sb, byte b) {
092 sb.append('%');
093 sb.append(HEX_DIGITS[(b >> 4) & 0x0f]);
094 sb.append(HEX_DIGITS[(b >> 0) & 0x0f]);
095 }
096
097 }