001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.rngom.util;
027:
028: import java.net.URL;
029: import java.net.MalformedURLException;
030: import java.io.UnsupportedEncodingException;
031:
032: public class Uri {
033: private static String utf8 = "UTF-8";
034:
035: public static boolean isValid(String s) {
036: return isValidPercent(s) && isValidFragment(s)
037: && isValidScheme(s);
038: }
039:
040: private static final String HEX_DIGITS = "0123456789abcdef";
041:
042: public static String escapeDisallowedChars(String s) {
043: StringBuffer buf = null;
044: int len = s.length();
045: int done = 0;
046: for (;;) {
047: int i = done;
048: for (;;) {
049: if (i == len) {
050: if (done == 0)
051: return s;
052: break;
053: }
054: if (isExcluded(s.charAt(i)))
055: break;
056: i++;
057: }
058: if (buf == null)
059: buf = new StringBuffer();
060: if (i > done) {
061: buf.append(s.substring(done, i));
062: done = i;
063: }
064: if (i == len)
065: break;
066: for (i++; i < len && isExcluded(s.charAt(i)); i++)
067: ;
068: String tem = s.substring(done, i);
069: byte[] bytes;
070: try {
071: bytes = tem.getBytes(utf8);
072: } catch (UnsupportedEncodingException e) {
073: utf8 = "UTF8";
074: try {
075: bytes = tem.getBytes(utf8);
076: } catch (UnsupportedEncodingException e2) {
077: // Give up
078: return s;
079: }
080: }
081: for (int j = 0; j < bytes.length; j++) {
082: buf.append('%');
083: buf.append(HEX_DIGITS.charAt((bytes[j] & 0xFF) >> 4));
084: buf.append(HEX_DIGITS.charAt(bytes[j] & 0xF));
085: }
086: done = i;
087: }
088: return buf.toString();
089: }
090:
091: private static final String excluded = "<>\"{}|\\^`";
092:
093: private static boolean isExcluded(char c) {
094: return c <= 0x20 || c >= 0x7F || excluded.indexOf(c) >= 0;
095: }
096:
097: private static boolean isAlpha(char c) {
098: return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
099: }
100:
101: private static boolean isHexDigit(char c) {
102: return ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
103: || 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 == '-'
112: || c == '.';
113: }
114:
115: private static boolean isValidPercent(String s) {
116: int len = s.length();
117: for (int i = 0; i < len; i++)
118: if (s.charAt(i) == '%') {
119: if (i + 2 >= len)
120: return false;
121: else if (!isHexDigit(s.charAt(i + 1))
122: || !isHexDigit(s.charAt(i + 2)))
123: return false;
124: }
125: return true;
126: }
127:
128: private static boolean isValidFragment(String s) {
129: int i = s.indexOf('#');
130: return i < 0 || s.indexOf('#', i + 1) < 0;
131: }
132:
133: private static boolean isValidScheme(String s) {
134: if (!isAbsolute(s))
135: return true;
136: int i = s.indexOf(':');
137: if (i == 0 || i + 1 == s.length() || !isAlpha(s.charAt(0)))
138: return false;
139: while (--i > 0)
140: if (!isSchemeChar(s.charAt(i)))
141: return false;
142: return true;
143: }
144:
145: public static String resolve(String baseUri, String uriReference) {
146: if (!isAbsolute(uriReference) && baseUri != null
147: && isAbsolute(baseUri)) {
148: try {
149: return new URL(new URL(baseUri), uriReference)
150: .toString();
151: } catch (MalformedURLException e) {
152: }
153: }
154: return uriReference;
155: }
156:
157: public static boolean hasFragmentId(String uri) {
158: return uri.indexOf('#') >= 0;
159: }
160:
161: public static boolean isAbsolute(String uri) {
162: int i = uri.indexOf(':');
163: if (i < 0)
164: return false;
165: while (--i >= 0) {
166: switch (uri.charAt(i)) {
167: case '#':
168: case '/':
169: case '?':
170: return false;
171: }
172: }
173: return true;
174: }
175: }
|