1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 package org.apache.myfaces.custom.util;
21
22 /**
23 * This utility class provides equivalents to the
24 * JavaScript encodeURIComponent(uri) and decodeURIComponent(encodedURI) functions.
25 *
26 * @author Gerald Müllan Date: 11.02.2007 Time: 23:30:08
27 */
28 public abstract class URIComponentUtils
29 {
30
31 public static String encodeURIComponent(String uri)
32 {
33 throw new UnsupportedOperationException("Not implemented yet!");
34 }
35
36 /**
37 * In case of incoming Strings - encoded with js encodeURIComponent()
38 * e.g. ö -> %C3%B6 - it is not sufficient to set CharacterEncoding on the
39 * ResponseWriter accordingly. Passing the uri to decodeURIComponent(String encodedURI)
40 * decodes e.g. %C3%B6 back to ö.
41 * @return decoded uri String
42 * @param encoded uri String
43 */
44 public static String decodeURIComponent(String encodedURI)
45 {
46 char actualChar;
47
48 StringBuffer buffer = new StringBuffer();
49
50 int bytePattern, sumb = 0;
51
52 for (int i = 0, more = -1; i < encodedURI.length(); i++)
53 {
54 actualChar = encodedURI.charAt(i);
55
56 switch (actualChar)
57 {
58 case'%':
59 {
60 actualChar = encodedURI.charAt(++i);
61 int hb = (Character.isDigit(actualChar) ? actualChar - '0'
62 : 10 + Character.toLowerCase(actualChar) - 'a') & 0xF;
63 actualChar = encodedURI.charAt(++i);
64 int lb = (Character.isDigit(actualChar) ? actualChar - '0'
65 : 10 + Character.toLowerCase(actualChar) - 'a') & 0xF;
66 bytePattern = (hb << 4) | lb;
67 break;
68 }
69 case'+':
70 {
71 bytePattern = ' ';
72 break;
73 }
74 default:
75 {
76 bytePattern = actualChar;
77 }
78 }
79
80 //* Decode byte bytePattern as UTF-8, sumb collects incomplete chars *//*
81 if ((bytePattern & 0xc0) == 0x80)
82 { // 10xxxxxx
83 sumb = (sumb << 6) | (bytePattern & 0x3f);
84 if (--more == 0) buffer.append((char) sumb);
85 }
86 else if ((bytePattern & 0x80) == 0x00)
87 { // 0xxxxxxx
88 buffer.append((char) bytePattern);
89 }
90 else if ((bytePattern & 0xe0) == 0xc0)
91 { // 110xxxxx
92 sumb = bytePattern & 0x1f;
93 more = 1;
94 }
95 else if ((bytePattern & 0xf0) == 0xe0)
96 { // 1110xxxx
97 sumb = bytePattern & 0x0f;
98 more = 2;
99 }
100 else if ((bytePattern & 0xf8) == 0xf0)
101 { // 11110xxx
102 sumb = bytePattern & 0x07;
103 more = 3;
104 }
105 else if ((bytePattern & 0xfc) == 0xf8)
106 { // 111110xx
107 sumb = bytePattern & 0x03;
108 more = 4;
109 }
110 else
111 { // 1111110x
112 sumb = bytePattern & 0x01;
113 more = 5;
114 }
115 }
116 return buffer.toString();
117 }
118 }