/* ############################################################################### # # # Copyright (C) 2011-2016 OpenMEAP, Inc. # # Credits to Jonathan Schang & Rob Thacher # # # # Released under the LGPLv3 # # # # OpenMEAP is free software: you can redistribute it and/or modify # # it under the terms of the GNU Lesser General Public License as published # # by the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # OpenMEAP is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU Lesser General Public License for more details. # # # # You should have received a copy of the GNU Lesser General Public License # # along with OpenMEAP. If not, see <http://www.gnu.org/licenses/>. # # # ############################################################################### */ package com.openmeap.util; import java.io.UnsupportedEncodingException; import com.openmeap.constants.FormConstants; /** * Utility class for JavaScript compatible UTF-8 encoding and decoding. * * @author schang */ final public class URIEncodingUtil { private URIEncodingUtil() {} private final static String PERCENT = "%"; /** * Decodes the passed UTF-8 String using an algorithm that's compatible with * JavaScript's <code>decodeURIComponent</code> function. Returns * <code>null</code> if the String is <code>null</code>. * * @param s The UTF-8 encoded String to be decoded * @return the decoded String */ public static String decodeURIComponent(String s) { if (s == null) { return null; } String result = s; result = StringUtils.replaceAll(result, "+", "%20"); result = StringUtils.replaceAll(result, "!", "%21"); result = StringUtils.replaceAll(result, "'", "%27"); result = StringUtils.replaceAll(result, "(", "%28"); result = StringUtils.replaceAll(result, ")", "%29"); result = StringUtils.replaceAll(result, "~", "%7E"); StringBuffer sb = new StringBuffer(); int d = result.length(); for(int i=0; i<d; i++ ) { char thisChar = result.charAt(i); if(thisChar=='%') { if(i+2>=d) { throw new URIEncodingException("Expecting an encoded char at index "+i); } char[] chars = new char[]{result.charAt(i+1),result.charAt(i+2)}; i+=2; char value = CharUtils.toChar(new String(chars)); sb.append(value); } else { sb.append(thisChar); } } return sb.toString(); } /** * Encodes the passed String as UTF-8 using an algorithm that's compatible * with JavaScript's <code>encodeURIComponent</code> function. Returns * <code>null</code> if the String is <code>null</code>. * * @param s The String to be encoded * @return the encoded String */ public static String encodeURIComponent(String s) { StringBuffer sb = new StringBuffer(); int d = s.length(); for(int i=0; i<d; i++ ) { char thisChar = s.charAt(i); if(Character.isDigit(thisChar) ||Character.isLowerCase(thisChar) ||Character.isUpperCase(thisChar)) { sb.append(thisChar); } else { byte[] thisByte = CharUtils.bytesValue(thisChar); sb.append(PERCENT); sb.append(Utils.byteArray2Hex(thisByte)); } } String result = sb.toString(); result = StringUtils.replaceAll(result, "%20", "+"); result = StringUtils.replaceAll(result, "%21", "!"); result = StringUtils.replaceAll(result, "%27", "'"); result = StringUtils.replaceAll(result, "%28", "("); result = StringUtils.replaceAll(result, "%29", ")"); result = StringUtils.replaceAll(result, "%7E", "~"); return result; } }