ugo 2004/05/05 15:21:09
Modified: src/java/org/apache/cocoon/util NetUtils.java
src/test/org/apache/cocoon/util/test NetUtilsTestCase.java
Log:
Porting fixes from 2.1
Revision Changes Path
1.10 +92 -69 cocoon-2.2/src/java/org/apache/cocoon/util/NetUtils.java
Index: NetUtils.java
===================================================================
RCS file: /home/cvs/cocoon-2.2/src/java/org/apache/cocoon/util/NetUtils.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- NetUtils.java 20 Apr 2004 16:10:52 -0000 1.9
+++ NetUtils.java 5 May 2004 22:21:09 -0000 1.10
@@ -19,15 +19,16 @@
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
-
import java.util.BitSet;
import java.util.Enumeration;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Map;
+import java.util.StringTokenizer;
-import org.apache.excalibur.source.SourceParameters;
import org.apache.cocoon.environment.Request;
import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.SourceParameters;
/**
* A collection of <code>File</code>, <code>URL</code> and filename
@@ -196,7 +197,6 @@
buf.reset();
}
}
-
return rewrittenPath.toString();
}
@@ -257,23 +257,16 @@
* @return The absolutized resource path
*/
public static String absolutize(String path, String resource) {
- if (path == null || path.length() == 0) {
- // Base path is empty
+ if (StringUtils.isEmpty(path)) {
return resource;
- }
-
- if (resource == null || resource.length() == 0) {
- // Resource path is empty
+ } else if (StringUtils.isEmpty(resource)) {
return path;
- }
-
- if (resource.charAt(0) == '/') {
+ } else if (resource.charAt(0) == '/') {
// Resource path is already absolute
return resource;
}
-
- int length = path.length() - 1;
- boolean slash = (path.charAt(length) == '/');
+
+ boolean slash = (path.charAt(path.length() - 1) == '/');
StringBuffer b = new StringBuffer();
b.append(path);
@@ -292,14 +285,14 @@
* @return the resource relative to the given path
*/
public static String relativize(String path, String absoluteResource) {
- if (path == null || "".equals(path)) {
+ if (StringUtils.isEmpty(path)) {
return absoluteResource;
}
-
+
if (path.charAt(path.length() - 1) != '/') {
path += "/";
}
-
+
if (absoluteResource.startsWith(path)) {
// resource is direct descentant
return absoluteResource.substring(path.length());
@@ -329,58 +322,51 @@
* @return The normalized uri
*/
public static String normalize(String uri) {
- String[] dirty = StringUtils.split(uri, "/");
- int length = dirty.length;
- String[] clean = new String[length];
-
- boolean path;
- boolean finished;
- while (true) {
- path = false;
- finished = true;
- for (int i = 0, j = 0; (i < length) && (dirty[i] != null); i++) {
- if (".".equals(dirty[i])) {
- // ignore
- } else if ("..".equals(dirty[i])) {
- clean[j++] = dirty[i];
- if (path) finished = false;
- } else {
- if ((i+1 < length) && ("..".equals(dirty[i+1]))) {
- i++;
- } else {
- clean[j++] = dirty[i];
- path = true;
+ if ("".equals(uri)) {
+ return uri;
+ }
+ int leadingSlashes = 0;
+ for (leadingSlashes = 0 ; leadingSlashes < uri.length()
+ && uri.charAt(leadingSlashes) == '/' ; ++leadingSlashes) {}
+ boolean isDir = (uri.charAt(uri.length() - 1) == '/');
+ StringTokenizer st = new StringTokenizer(uri, "/");
+ LinkedList clean = new LinkedList();
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if ("..".equals(token)) {
+ if (! clean.isEmpty() && ! "..".equals(clean.getLast())) {
+ clean.removeLast();
+ if (! st.hasMoreTokens()) {
+ isDir = true;
}
+ } else {
+ clean.add("..");
}
- }
- if (finished) {
- break;
- } else {
- dirty = clean;
- clean = new String[length];
+ } else if (! ".".equals(token) && ! "".equals(token)) {
+ clean.add(token);
}
}
-
- StringBuffer b = new StringBuffer(uri.length());
-
- // Added this check to satisfy NetUtilsTestCase. I cannot ascertain
whether
- // this is correct or not, since the description of this method is
not very
- // clear. [Ugo Cei <[EMAIL PROTECTED]> 2004-04-19]
- if (uri.charAt(0) == '/') {
- b.append('/');
+ StringBuffer sb = new StringBuffer();
+ while (leadingSlashes-- > 0) {
+ sb.append('/');
+ }
+ for (Iterator it = clean.iterator() ; it.hasNext() ; ) {
+ sb.append(it.next());
+ if (it.hasNext()) {
+ sb.append('/');
+ }
}
-
- for (int i = 0; (i < length) && (clean[i] != null); i++) {
- b.append(clean[i]);
- if ((i+1 < length) && (clean[i+1] != null)) b.append("/");
+ if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') {
+ sb.append('/');
}
-
- return b.toString();
+ return sb.toString();
}
/**
* Remove parameters from a uri.
- *
+ * Resulting Map will have either String for single value attributes,
+ * or String arrays for multivalue attributes.
+ *
* @param uri The uri path to deparameterize.
* @param parameters The map that collects parameters.
* @return The cleaned uri
@@ -390,8 +376,8 @@
if (i == -1) {
return uri;
}
-
- String[] params = StringUtils.split(uri.substring(i + 1), "&");
+
+ String[] params = StringUtils.split(uri.substring(i + 1), '&');
for (int j = 0; j < params.length; j++) {
String p = params[j];
int k = p.indexOf('=');
@@ -399,24 +385,61 @@
break;
}
String name = p.substring(0, k);
- String value = p.substring(k+1);
- parameters.put(name, value);
+ String value = p.substring(k + 1);
+ Object values = parameters.get(name);
+ if (values == null) {
+ parameters.put(name, value);
+ } else if (values.getClass().isArray()) {
+ String[] v1 = (String[])values;
+ String[] v2 = new String[v1.length + 1];
+ System.arraycopy(v1, 0, v2, 0, v1.length);
+ v2[v1.length] = value;
+ parameters.put(name, v2);
+ } else {
+ parameters.put(name, new String[]{values.toString(), value});
+ }
}
return uri.substring(0, i);
}
+ /**
+ * Add parameters stored in the Map to the uri string.
+ * Map can contain Object values which will be converted to the string,
+ * or Object arrays, which will be treated as multivalue attributes.
+ *
+ * @param uri The uri to add parameters into
+ * @param parameters The map containing parameters to be added
+ * @return The uri with added parameters
+ */
public static String parameterize(String uri, Map parameters) {
if (parameters.size() == 0) {
return uri;
}
StringBuffer buffer = new StringBuffer(uri);
- buffer.append('?');
+ if (uri.indexOf('?') == -1) {
+ buffer.append('?');
+ } else {
+ buffer.append('&');
+ }
+
for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
- buffer.append(entry.getKey());
- buffer.append('=');
- buffer.append(entry.getValue());
+ if (entry.getValue().getClass().isArray()) {
+ Object[] value = (Object[])entry.getValue();
+ for (int j = 0; j < value.length; j++) {
+ if (j > 0) {
+ buffer.append('&');
+ }
+ buffer.append(entry.getKey());
+ buffer.append('=');
+ buffer.append(value[j]);
+ }
+ } else {
+ buffer.append(entry.getKey());
+ buffer.append('=');
+ buffer.append(entry.getValue());
+ }
if (i.hasNext()) {
buffer.append('&');
}
1.6 +17 -6
cocoon-2.2/src/test/org/apache/cocoon/util/test/NetUtilsTestCase.java
Index: NetUtilsTestCase.java
===================================================================
RCS file:
/home/cvs/cocoon-2.2/src/test/org/apache/cocoon/util/test/NetUtilsTestCase.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- NetUtilsTestCase.java 8 Mar 2004 14:04:20 -0000 1.5
+++ NetUtilsTestCase.java 5 May 2004 22:21:09 -0000 1.6
@@ -63,6 +63,7 @@
*/
public void testGetPath() throws Exception {
Object[] test_values = {
+ new String[]{"", ""},
new String[]{"/", ""},
new String[]{"/foo.bar", ""},
new String[]{"foo/bar", "foo"},
@@ -198,23 +199,33 @@
/**
- * A unit test for <code>NetUtils.normalize()</code>
- *
- * @exception Exception Description of Exception
- * @since
+ * A unit test for [EMAIL PROTECTED] NetUtils#normalize(String)}
*/
public void testNormalize() throws Exception {
Object[] test_values = {
+ new String[]{"", ""},
+ new String[]{"/", "/"},
+ new String[]{"/../", "/../"},
+ new String[]{"/../../", "/../../"},
+ new String[]{"/../../foo", "/../../foo"},
+ new String[]{"/../../foo//./../bar", "/../../bar"},
+ new String[]{"//foo//bar", "//foo/bar"},
+ new String[]{"//foo//./bar", "//foo/bar"},
new String[]{"/foo/bar", "/foo/bar"},
+ new String[]{"/foo/bar/", "/foo/bar/"},
+ new String[]{"/foo/../bar", "/bar"},
+ new String[]{"/foo/../bar/", "/bar/"},
new String[]{"bar", "bar"},
new String[]{"foo/../bar", "bar"},
new String[]{"foo/./bar", "foo/bar"},
- new String[]{"foo/bar1/bar2/bar3/../../..", "foo"},
+ new String[]{"foo/bar1/bar2/bar3/../../..", "foo/"},
};
for (int i = 0; i < test_values.length; i++) {
String tests[] = (String[]) test_values[i];
String test = tests[0];
String expected = tests[1];
+ // alternative for JDK 1.4
+ //String expected = new
java.net.URI(test).normalize().toString();
String result = NetUtils.normalize(test);
String message = "Test " + "'" + test + "'";