1 /* 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.rngom.util; 27 28 import java.net.URL; 29 import java.net.MalformedURLException; 30 import java.io.UnsupportedEncodingException; 31 32 public class Uri { 33 private static String utf8 = "UTF-8"; 34 35 public static boolean isValid(String s) { 36 return isValidPercent(s) && isValidFragment(s) && isValidScheme(s); 37 } 38 39 private static final String HEX_DIGITS = "0123456789abcdef"; 40 41 public static String escapeDisallowedChars(String s) { 42 StringBuffer buf = null; 43 int len = s.length(); 44 int done = 0; 45 for (;;) { 46 int i = done; 47 for (;;) { 48 if (i == len) { 49 if (done == 0) 50 return s; 51 break; 52 } 53 if (isExcluded(s.charAt(i))) 54 break; 55 i++; 56 } 57 if (buf == null) 58 buf = new StringBuffer(); 59 if (i > done) { 60 buf.append(s.substring(done, i)); 61 done = i; 62 } 63 if (i == len) 64 break; 65 for (i++; i < len && isExcluded(s.charAt(i)); i++) 66 ; 67 String tem = s.substring(done, i); 68 byte[] bytes; 69 try { 70 bytes = tem.getBytes(utf8); 71 } 72 catch (UnsupportedEncodingException e) { 73 utf8 = "UTF8"; 74 try { 75 bytes = tem.getBytes(utf8); 76 } 77 catch (UnsupportedEncodingException e2) { 78 // Give up 79 return s; 80 } 81 } 82 for (int j = 0; j < bytes.length; j++) { 83 buf.append('%'); 84 buf.append(HEX_DIGITS.charAt((bytes[j] & 0xFF) >> 4)); 85 buf.append(HEX_DIGITS.charAt(bytes[j] & 0xF)); 86 } 87 done = i; 88 } 89 return buf.toString(); 90 } 91 92 private static final String excluded = "<>\"{}|\\^`"; 93 94 private static boolean isExcluded(char c) { 95 return c <= 0x20 || c >= 0x7F || excluded.indexOf(c) >= 0; 96 } 97 98 private static boolean isAlpha(char c) { 99 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 100 } 101 102 private static boolean isHexDigit(char c) { 103 return ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || isDigit(c); 104 } 105 106 private static boolean isDigit(char c) { 107 return '0' <= c && c <= '9'; 108 } 109 110 private static boolean isSchemeChar(char c) { 111 return isAlpha(c) || isDigit(c) || c == '+' || c == '-' || c =='.'; 112 } 113 114 private static boolean isValidPercent(String s) { 115 int len = s.length(); 116 for (int i = 0; i < len; i++) 117 if (s.charAt(i) == '%') { 118 if (i + 2 >= len) 119 return false; 120 else if (!isHexDigit(s.charAt(i + 1)) 121 || !isHexDigit(s.charAt(i + 2))) 122 return false; 123 } 124 return true; 125 } 126 127 private static boolean isValidFragment(String s) { 128 int i = s.indexOf('#'); 129 return i < 0 || s.indexOf('#', i + 1) < 0; 130 } 131 132 private static boolean isValidScheme(String s) { 133 if (!isAbsolute(s)) 134 return true; 135 int i = s.indexOf(':'); 136 if (i == 0 137 || i + 1 == s.length() 138 || !isAlpha(s.charAt(0))) 139 return false; 140 while (--i > 0) 141 if (!isSchemeChar(s.charAt(i))) 142 return false; 143 return true; 144 } 145 146 public static String resolve(String baseUri, String uriReference) { 147 if (!isAbsolute(uriReference) && baseUri != null && isAbsolute(baseUri)) { 148 try { 149 return new URL(new URL(baseUri), uriReference).toString(); 150 } 151 catch (MalformedURLException e) { } 152 } 153 return uriReference; 154 } 155 156 public static boolean hasFragmentId(String uri) { 157 return uri.indexOf('#') >= 0; 158 } 159 160 public static boolean isAbsolute(String uri) { 161 int i = uri.indexOf(':'); 162 if (i < 0) 163 return false; 164 while (--i >= 0) { 165 switch (uri.charAt(i)) { 166 case '#': 167 case '/': 168 case '?': 169 return false; 170 } 171 } 172 return true; 173 } 174 }