jericho 2003/01/20 20:02:07
Modified: src/util/org/apache/util URI.java
Log:
- Add setXxxPath methods to set path correctly
Reported by 'Armando_Anton <armando.anton at newknow.com>'
- Force API programmer to inform the charset changed with exception to users
Revision Changes Path
1.25 +224 -25 jakarta-slide/src/util/org/apache/util/URI.java
Index: URI.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/util/org/apache/util/URI.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- URI.java 5 Jan 2003 07:56:09 -0000 1.24
+++ URI.java 21 Jan 2003 04:02:07 -0000 1.25
@@ -891,6 +891,7 @@
protected static final BitSet opaque_part = new BitSet(256);
// Static initializer for opaque_part
static {
+ // it's generous. because first character must not include a slash
opaque_part.or(uric_no_slash);
opaque_part.or(uric);
}
@@ -1927,7 +1928,11 @@
_path = null;
}
}
- setPath(tmp.substring(from, next));
+ if (escaped) {
+ setRawPath(tmp.substring(from, next).toCharArray());
+ } else {
+ setPath(tmp.substring(from, next));
+ }
at = next;
}
@@ -2376,10 +2381,37 @@
* An individual URI scheme may require a single charset, define a default
* charset, or provide a way to indicate the charset used.
*
+ * <p>
+ * Always all the time, the setter method is always succeeded and throws
+ * <code>CharsetChanged</code> exception.
+ *
+ * So API programmer must follow the following way:
+ * <code>
+ * import org.apache.util.URI$CharsetChanged;
+ * .
+ * .
+ * .
+ * try {
+ * URI.setProtocolCharset("UTF-8");
+ * } catch (CharsetChanged cc) {
+ * if (cc.getReasonCode() == CharsetChanged.PROTOCOL_CHARSET) {
+ * // let user know the default protocol charset changed
+ * } else {
+ * // let user know the default document charset changed
+ * }
+ * }
+ * </code>
+ *
+ * The API programmer is responsible to set the correct charset.
+ * And each application should remember its own charset to support.
+ *
* @param charset the default charset for each protocol
+ * @throws CharsetChanged charset changed
*/
public static void setProtocolCharset(String charset) {
_protocolCharset = charset;
+ throw new CharsetChanged(CharsetChanged.PROTOCOL_CHARSET,
+ "the default protocol charset changed");
}
@@ -2410,11 +2442,38 @@
* display of these character sets, the protocol charset could be simply
* used again. Because it's not yet implemented that the insertion of BIDI
* control characters at different points during composition is extracted.
+ * <p>
+ *
+ * Always all the time, the setter method is always succeeded and throws
+ * <code>CharsetChanged</code> exception.
+ *
+ * So API programmer must follow the following way:
+ * <code>
+ * import org.apache.util.URI$CharsetChanged;
+ * .
+ * .
+ * .
+ * try {
+ * URI.setDocumentCharset("EUC-KR");
+ * } catch (CharsetChanged cc) {
+ * if (cc.getReasonCode() == CharsetChanged.DOCUMENT_CHARSET) {
+ * // let user know the default document charset changed
+ * } else {
+ * // let user know the default protocol charset changed
+ * }
+ * }
+ * </code>
+ *
+ * The API programmer is responsible to set the correct charset.
+ * And each application should remember its own charset to support.
*
* @param charset the default charset for the document
+ * @throws CharsetChanged charset changed
*/
public static void setDocumentCharset(String charset) {
_documentCharset = charset;
+ throw new CharsetChanged(CharsetChanged.DOCUMENT_CHARSET,
+ "the default document charset changed");
}
@@ -2600,21 +2659,90 @@
// --------------------------------------------------------------- The path
/**
- * Set the path. The method couldn't be used by API programmers.
+ * Set the raw-escaped path.
+ *
+ * @param escapedPath the path character sequence
+ * @exception URIException encoding error or not proper for initial instance
+ * @see #encode
+ */
+ public void setRawPath(char[] escapedPath) throws URIException {
+ if (escapedPath == null || escapedPath.length == 0) {
+ _path = _opaque = escapedPath;
+ setURI();
+ return;
+ }
+ // remove the fragment identifier
+ escapedPath = removeFragmentIdentifier(escapedPath);
+ if (_is_net_path || _is_abs_path) {
+ if (escapedPath[0] != '/')
+ throw new URIException(URIException.PARSING,
+ "not absolute path");
+ if (!validate(escapedPath, abs_path))
+ throw new URIException(URIException.ESCAPING,
+ "escaped absolute path not valid");
+ _path = escapedPath;
+ } else if (_is_rel_path) {
+ int at = indexFirstOf(escapedPath, '/');
+ if (at == 0)
+ throw new URIException(URIException.PARSING, "incorrect path");
+ if (at > 0 && !validate(escapedPath, 0, at, rel_segment) ||
+ at < 0 && !validate(escapedPath, 0, -1, abs_path))
+ throw new URIException(URIException.ESCAPING,
+ "escaped relative path not valid");
+ _path = escapedPath;
+ } else if (_is_opaque_part) {
+ if (!uric_no_slash.get(escapedPath[0]) &&
+ !validate(escapedPath, 1, -1, uric))
+ throw new URIException(URIException.ESCAPING,
+ "escaped opaque part not valid");
+ _opaque = escapedPath;
+ } else {
+ throw new URIException(URIException.PARSING, "incorrect path");
+ }
+ setURI();
+ }
+
+
+ /**
+ * Set the escaped path.
+ *
+ * @param escapedPath the escaped path string
+ * @exception URIException encoding error or not proper for initial instance
+ * @see #encode
+ */
+ public void setEscapedPath(String escapedPath) throws URIException {
+ if (escapedPath == null) {
+ _path = _opaque = null;
+ setURI();
+ return;
+ }
+ setRawPath(escapedPath.toCharArray());
+ }
+
+
+ /**
+ * Set the path.
*
* @param path the path string
* @exception URIException set incorrectly or fragment only
* @see #encode
*/
- protected void setPath(String path) throws URIException {
+ public void setPath(String path) throws URIException {
- // set path
+ if (path == null || path.length() == 0) {
+ _path = _opaque = (path == null) ? null : path.toCharArray();
+ setURI();
+ return;
+ }
if (_is_net_path || _is_abs_path) {
_path = encode(path, allowed_abs_path);
} else if (_is_rel_path) {
StringBuffer buff = new StringBuffer(path.length());
int at = path.indexOf('/');
- if (at > 0) { // never 0
+ if (at == 0) // never 0
+ throw new URIException(URIException.PARSING,
+ "incorrect relative path");
+ if (at > 0) {
buff.append(encode(path.substring(0, at), allowed_rel_path));
buff.append(encode(path.substring(at), allowed_abs_path));
} else {
@@ -2622,10 +2750,14 @@
}
_path = buff.toString().toCharArray();
} else if (_is_opaque_part) {
- _opaque = encode(path, allowed_opaque_part);
+ StringBuffer buf = new StringBuffer();
+ buf.insert(0, encode(path.substring(0, 1), uric_no_slash));
+ buf.insert(1, encode(path.substring(1), uric));
+ _opaque = buf.toString().toCharArray();
} else {
throw new URIException(URIException.PARSING, "incorrect path");
}
+ setURI();
}
@@ -2911,8 +3043,8 @@
* @exception URIException escaped query not valid
*/
public void setRawQuery(char[] escapedQuery) throws URIException {
- if (escapedQuery == null) {
- _query = null;
+ if (escapedQuery == null || escapedQuery.length == 0) {
+ _query = escapedQuery;
setURI();
return;
}
@@ -2960,8 +3092,8 @@
* @see #encode
*/
public void setQuery(String query) throws URIException {
- if (query == null) {
- _query = null;
+ if (query == null || query.length() == 0) {
+ _query = (query == null) ? null : query.toCharArray();
setURI();
return;
}
@@ -3010,8 +3142,8 @@
* @exception URIException escaped fragment not valid
*/
public void setRawFragment(char[] escapedFragment) throws URIException {
- if (escapedFragment == null) {
- _fragment = null;
+ if (escapedFragment == null || escapedFragment.length == 0) {
+ _fragment = escapedFragment;
return;
}
if (!validate(escapedFragment, fragment))
@@ -3033,12 +3165,7 @@
_fragment = null;
return;
}
- char[] fragmentSequence = escapedFragment.toCharArray();
- if (!validate(fragmentSequence, fragment))
- throw new URIException(URIException.ESCAPING,
- "escaped fragment not valid");
- _fragment = fragmentSequence;
- setURI();
+ setRawFragment(escapedFragment.toCharArray());
}
@@ -3049,8 +3176,8 @@
* @exception URIException
*/
public void setFragment(String fragment) throws URIException {
- if (fragment == null) {
- _fragment = null;
+ if (fragment == null || fragment.length() == 0) {
+ _fragment = (fragment == null) ? null : fragment.toCharArray();
return;
}
_fragment = encode(fragment, allowed_fragment);
@@ -3447,7 +3574,7 @@
* password to access manually. Probably it will be supported in the each
* subclass, however, not a whole URI-reference expression.
*
- * @return the URI string
+ * @return the escaped URI string
* @see #clone()
*/
public String toString() {
@@ -3456,6 +3583,78 @@
// ------------------------------------------------------------ Inner class
+
+ /**
+ * The charset-changed normal operation to represent to be required to
+ * alert to user the fact the default charset is changed.
+ */
+ public static class CharsetChanged extends RuntimeException {
+
+ // ------------------------------------------------------- constructors
+
+ /**
+ * The constructor with a reason string and its code arguments.
+ *
+ * @param reasonCode the reason code
+ * @param reason the reason
+ */
+ public CharsetChanged(int reasonCode, String reason) {
+ super(reason);
+ this.reason = reason;
+ this.reasonCode = reasonCode;
+ }
+
+ // ---------------------------------------------------------- constants
+
+ /**
+ * No specified reason code.
+ */
+ public static final int UNKNOWN = 0;
+
+ /**
+ * Protocol charset changed.
+ */
+ public static final int PROTOCOL_CHARSET = 1;
+
+ /**
+ * Document charset changed.
+ */
+ public static final int DOCUMENT_CHARSET = 2;
+
+ // ------------------------------------------------- instance variables
+
+ /**
+ * The reason code.
+ */
+ private int reasonCode;
+
+ /**
+ * The reason message.
+ */
+ private String reason;
+
+ // ------------------------------------------------------------ methods
+
+ /**
+ * Get the reason code.
+ *
+ * @return the reason code
+ */
+ public int getReasonCode() {
+ return reasonCode;
+ }
+
+ /**
+ * Get the reason message.
+ *
+ * @return the reason message
+ */
+ public String getReason() {
+ return reason;
+ }
+
+ }
+
/**
* A mapping to determine the (somewhat arbitrarily) preferred charset for
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>