Author: fguillaume
Date: Wed Sep 29 14:04:54 2010
New Revision: 1002636
URL: http://svn.apache.org/viewvc?rev=1002636&view=rev
Log:
CMIS-255: fix multi-segment atompub servlet path
Modified:
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/UrlBuilder.java
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/test/java/org/apache/chemistry/opencmis/commons/impl/misc/MiscTest.java
incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/AtomPubUtils.java
Modified:
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/UrlBuilder.java
URL:
http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/UrlBuilder.java?rev=1002636&r1=1002635&r2=1002636&view=diff
==============================================================================
---
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/UrlBuilder.java
(original)
+++
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/UrlBuilder.java
Wed Sep 29 14:04:54 2010
@@ -19,6 +19,7 @@
package org.apache.chemistry.opencmis.commons.impl;
import java.io.UnsupportedEncodingException;
+import java.net.URI;
import java.net.URLEncoder;
import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
@@ -137,23 +138,57 @@ public class UrlBuilder {
* @param pathSegment
* the path segment.
*/
- public void addPath(String pathSegment) {
- if ((pathSegment == null) || (pathSegment.length() == 0)) {
+ public void addPathSegment(String pathSegment) {
+ addPathPart(pathSegment, true);
+ }
+
+ /**
+ * Adds a path to the URL.
+ *
+ * @param path the path
+ */
+ public void addPath(String path) {
+ addPathPart(path, false);
+ }
+
+ protected void addPathPart(String part, boolean quoteSlash) {
+ if (part == null || part.length() == 0) {
return;
}
-
if (fUrl.charAt(fUrl.length() - 1) != '/') {
fUrl.append('/');
}
-
- if (pathSegment.charAt(0) == '/') {
- pathSegment = pathSegment.substring(1);
+ if (part.charAt(0) == '/') {
+ part = part.substring(1);
}
+ fUrl.append(quoteURIPathComponent(part, quoteSlash));
+ }
+ public static char[] RFC7232_RESERVED = ";?:@&=+$,[]".toCharArray();
+
+ public static String quoteURIPathComponent(String s, boolean quoteSlash) {
+ if (s.length() == 0) {
+ return s;
+ }
+ // reuse the URI class which knows a lot about escaping
+ URI uri;
try {
- fUrl.append(URLEncoder.encode(pathSegment, "UTF-8"));
- } catch (UnsupportedEncodingException e) {
+ // fake scheme so that a colon is not mistaken as a scheme
+ uri = new URI("x", s, null);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Illegal characters in: " + s,
e);
+ }
+ String r = uri.toASCIIString().substring(2); // remove x:
+ // quote some additional reserved characters to be safe
+ for (char c : RFC7232_RESERVED) {
+ if (r.indexOf(c) >= 0) {
+ r = r.replace(""+c, "%" + Integer.toHexString(c));
+ }
+ }
+ if (quoteSlash && r.indexOf('/') >= 0) {
+ r = r.replace("/", "%2F");
}
+ return r;
}
/**
Modified:
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/test/java/org/apache/chemistry/opencmis/commons/impl/misc/MiscTest.java
URL:
http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/test/java/org/apache/chemistry/opencmis/commons/impl/misc/MiscTest.java?rev=1002636&r1=1002635&r2=1002636&view=diff
==============================================================================
---
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/test/java/org/apache/chemistry/opencmis/commons/impl/misc/MiscTest.java
(original)
+++
incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/test/java/org/apache/chemistry/opencmis/commons/impl/misc/MiscTest.java
Wed Sep 29 14:04:54 2010
@@ -15,17 +15,19 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ * Contributors:
+ * Florian Mueller
+ * Florent Guillaume, Nuxeo
*/
package org.apache.chemistry.opencmis.commons.impl.misc;
-import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
-
import junit.framework.TestCase;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+
/**
* Tests miscellaneous details.
- *
- * @author <a href="mailto:[email protected]">Florian Müller</a>
*/
public class MiscTest extends TestCase {
@@ -33,7 +35,26 @@ public class MiscTest extends TestCase {
assertEquals("http://host/test", (new
UrlBuilder("http://host/test")).toString());
assertEquals("http://host/test?query=value", (new
UrlBuilder("http://host/test?query=value")).toString());
assertEquals("http://host/test", (new
UrlBuilder("http://host/test?")).toString());
+ }
+ public void testUrlBuilderAddParameter() {
+ UrlBuilder urlBuilder;
+
+ urlBuilder = new UrlBuilder("http://host/test");
+ urlBuilder.addParameter("query", "value");
+ assertEquals("http://host/test?query=value", urlBuilder.toString());
+
+ urlBuilder = new UrlBuilder("http://host/test?foo=bar");
+ urlBuilder.addParameter("query", "value");
+ assertEquals("http://host/test?foo=bar&query=value",
urlBuilder.toString());
+
+ // special chars, space turns into plus
+ urlBuilder = new UrlBuilder("http://host/test");
+ urlBuilder.addParameter("query", "caf\u00e9 cr\u00e8me");
+ assertEquals("http://host/test?query=caf%C3%A9+cr%C3%A8me",
urlBuilder.toString());
+ }
+
+ public void testUrlBuilderAddPath() {
UrlBuilder urlBuilder;
urlBuilder = new UrlBuilder("http://host/test");
@@ -55,5 +76,40 @@ public class MiscTest extends TestCase {
urlBuilder = new UrlBuilder("http://host/test/");
urlBuilder.addPath("/path");
assertEquals("http://host/test/path", urlBuilder.toString());
+
+ // multi-segment path with special chars, space turns into %20
+ urlBuilder = new UrlBuilder("http://host/test/");
+ urlBuilder.addPath("path/caf\u00e9 d...@d");
+ assertEquals("http://host/test/path/caf%C3%A9%20d%40d",
urlBuilder.toString());
+ }
+
+ public void testUrlBuilderAddPathSegment() {
+ UrlBuilder urlBuilder;
+
+ urlBuilder = new UrlBuilder("http://host/test");
+ urlBuilder.addParameter("query", "value");
+ assertEquals("http://host/test?query=value", urlBuilder.toString());
+
+ urlBuilder = new UrlBuilder("http://host/test");
+ urlBuilder.addPathSegment("path");
+ assertEquals("http://host/test/path", urlBuilder.toString());
+
+ urlBuilder = new UrlBuilder("http://host/test/");
+ urlBuilder.addPathSegment("path");
+ assertEquals("http://host/test/path", urlBuilder.toString());
+
+ urlBuilder = new UrlBuilder("http://host/test");
+ urlBuilder.addPathSegment("/path");
+ assertEquals("http://host/test/path", urlBuilder.toString());
+
+ urlBuilder = new UrlBuilder("http://host/test/");
+ urlBuilder.addPathSegment("/path");
+ assertEquals("http://host/test/path", urlBuilder.toString());
+
+ // with special chars and slash, space turns into %20
+ urlBuilder = new UrlBuilder("http://host/test/");
+ urlBuilder.addPathSegment("path/caf\u00e9 d...@d");
+ assertEquals("http://host/test/path%2Fcaf%C3%A9%20d%40d",
urlBuilder.toString());
}
+
}
Modified:
incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/AtomPubUtils.java
URL:
http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/AtomPubUtils.java?rev=1002636&r1=1002635&r2=1002636&view=diff
==============================================================================
---
incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/AtomPubUtils.java
(original)
+++
incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/AtomPubUtils.java
Wed Sep 29 14:04:54 2010
@@ -15,6 +15,10 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ * Contributors:
+ * Florian Mueller
+ * Florent Guillaume, Nuxeo
*/
package org.apache.chemistry.opencmis.server.impl.atompub;
@@ -90,7 +94,7 @@ public final class AtomPubUtils {
url.addPath(request.getServletPath());
if (repositoryId != null) {
- url.addPath(repositoryId);
+ url.addPathSegment(repositoryId);
}
return url;
@@ -108,7 +112,7 @@ public final class AtomPubUtils {
*/
public static UrlBuilder compileUrlBuilder(UrlBuilder baseUrl, String
resource, String id) {
UrlBuilder url = new UrlBuilder(baseUrl);
- url.addPath(resource);
+ url.addPathSegment(resource);
if (id != null) {
url.addParameter("id", id);
@@ -277,7 +281,7 @@ public final class AtomPubUtils {
if (info.hasContent()) {
UrlBuilder contentSrcBuilder = compileUrlBuilder(baseUrl,
RESOURCE_CONTENT, info.getId());
if (info.getFileName() != null) {
- contentSrcBuilder.addPath(info.getFileName());
+ contentSrcBuilder.addPathSegment(info.getFileName());
}
contentSrc = contentSrcBuilder.toString();