You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lenya.apache.org by an...@apache.org on 2011/01/02 11:32:44 UTC
svn commit: r1054381 - in
/lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java:
src/org/apache/lenya/cms/linking/ test/org/apache/lenya/cms/linking/
Author: andreas
Date: Sun Jan 2 10:32:43 2011
New Revision: 1054381
URL: http://svn.apache.org/viewvc?rev=1054381&view=rev
Log:
Improve relative URI rewriting (code simplification, better correctness).
Added:
lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UriUtil.java
lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/UriUtilTest.java
Modified:
lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/OutgoingLinkRewriter.java
lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/OutgoingLinkRewriterTest.java
Modified: lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/OutgoingLinkRewriter.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/OutgoingLinkRewriter.java?rev=1054381&r1=1054380&r2=1054381&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/OutgoingLinkRewriter.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/OutgoingLinkRewriter.java Sun Jan 2 10:32:43 2011
@@ -19,7 +19,6 @@ package org.apache.lenya.cms.linking;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -40,7 +39,6 @@ import org.apache.lenya.cms.publication.
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.publication.URLInformation;
import org.apache.lenya.cms.repository.Session;
-import org.apache.lenya.util.StringUtil;
/**
* <p>
@@ -65,12 +63,12 @@ public class OutgoingLinkRewriter extend
/**
* @param manager The service manager to use.
* @param session The current session.
- * @param requestUrl The requested web application URL (without servlet context path) where
- * the links should be rewritten.
+ * @param requestUrl The requested web application URL (without servlet context path) where the
+ * links should be rewritten.
* @param ssl If the current page is SSL-encrypted.
* @param considerSslPolicies If the SSL protection of policies should be considered when
- * resolving the corresponding proxy. Setting this to <code>true</code> leads to a
- * substantial performance overhead.
+ * resolving the corresponding proxy. Setting this to <code>true</code> leads to a
+ * substantial performance overhead.
* @param relativeUrls If relative URLs should be created.
*/
public OutgoingLinkRewriter(ServiceManager manager, Session session, String requestUrl,
@@ -129,43 +127,41 @@ public class OutgoingLinkRewriter extend
}
public boolean matches(String url) {
- return url.startsWith("/");
+ return url.equals("") || url.startsWith("/");
}
- private Map publicationCache = new HashMap();
+ private Map<String, Publication> publicationCache = new HashMap<String, Publication>();
protected Publication getPublication(String pubId) throws PublicationException {
- return (Publication) this.publicationCache.get(pubId);
+ return this.publicationCache.get(pubId);
}
public String rewrite(final String url) {
String rewrittenUrl = "";
-
+
String path;
String suffix;
-
+
int numIndex = url.indexOf('#');
if (numIndex > -1) {
path = url.substring(0, numIndex);
suffix = url.substring(numIndex);
- }
- else {
+ } else {
int qmIndex = url.indexOf('?');
if (qmIndex > -1) {
path = url.substring(0, qmIndex);
suffix = url.substring(qmIndex);
- }
- else {
+ } else {
path = url;
suffix = "";
}
}
-
+
try {
String normalizedUrl = normalizeUrl(path);
if (this.relativeUrls) {
- rewrittenUrl = getRelativeUrlTo(normalizedUrl);
+ rewrittenUrl = UriUtil.getRelativeUri(this.requestUrl, normalizedUrl);
} else {
boolean useSsl = this.ssl;
if (!useSsl && this.policyManager != null) {
@@ -200,18 +196,12 @@ public class OutgoingLinkRewriter extend
}
protected String normalizeUrl(final String url) throws URISyntaxException {
- String normalizedUrl;
- if (url.indexOf("..") > -1) {
- normalizedUrl = new URI(url).normalize().toString();
- } else {
- normalizedUrl = url;
- }
- return normalizedUrl;
+ return url.indexOf("..") > -1 ? new URI(url).normalize().toString() : url;
}
private String requestUrl;
- private Map pubId2areaList = new HashMap();
+ private Map<String, List<String>> pubId2areaList = new HashMap<String, List<String>>();
/**
* Checks if a publication has an area by using a cache for performance reasons.
@@ -221,7 +211,7 @@ public class OutgoingLinkRewriter extend
*/
protected boolean hasArea(Publication pub, String area) {
String pubId = pub.getId();
- List areas = (List) this.pubId2areaList.get(pubId);
+ List<String> areas = this.pubId2areaList.get(pubId);
if (areas == null) {
areas = Arrays.asList(pub.getAreaNames());
this.pubId2areaList.put(pubId, areas);
@@ -254,58 +244,4 @@ public class OutgoingLinkRewriter extend
return rewrittenUrl;
}
- protected String getRelativeUrlTo(String webappUrl) {
- String relativeUrl;
- if (this.requestUrl.equals(webappUrl)) {
- relativeUrl = getLastStep(webappUrl);
- }
- else {
- List sourceSteps = toList(this.requestUrl);
- List targetSteps = toList(webappUrl);
-
- String lastEqualStep = null;
-
- while (!sourceSteps.isEmpty() && !targetSteps.isEmpty()
- && sourceSteps.get(0).equals(targetSteps.get(0))) {
- lastEqualStep = (String) sourceSteps.remove(0);
- targetSteps.remove(0);
- }
-
- String prefix = "";
- if (targetSteps.isEmpty()) {
- prefix = generateUpDots(sourceSteps.size());
- }
- else if (sourceSteps.isEmpty()) {
- prefix = getLastStep(this.requestUrl) + "/";
- }
- else if (sourceSteps.size() > 1) {
- prefix = generateUpDots(sourceSteps.size() - 1) + "/";
- }
- else if (sourceSteps.size() == 1 && targetSteps.get(0).equals("")) {
- prefix = generateUpDots(1) + "/" + lastEqualStep + "/";
- }
-
- String[] targetArray = (String[]) targetSteps.toArray(new String[targetSteps.size()]);
- String targetPath = StringUtil.join(targetArray, "/");
- relativeUrl = prefix + targetPath;
- }
- return relativeUrl;
- }
-
- protected String getLastStep(String url) {
- return url.substring(url.lastIndexOf("/") + 1);
- }
-
- protected String generateUpDots(int length) {
- String upDots;
- String[] upDotsArray = new String[length];
- Arrays.fill(upDotsArray, "..");
- upDots = StringUtil.join(upDotsArray, "/");
- return upDots;
- }
-
- protected List toList(String url) {
- return new ArrayList(Arrays.asList(url.substring(1).split("/", -1)));
- }
-
}
Added: lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UriUtil.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UriUtil.java?rev=1054381&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UriUtil.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UriUtil.java Sun Jan 2 10:32:43 2011
@@ -0,0 +1,110 @@
+package org.apache.lenya.cms.linking;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.lenya.util.StringUtil;
+
+public class UriUtil {
+
+ public static String getRelativeUri(String sourceUri, String targetUri) {
+ final boolean empty = targetUri.equals("");
+ if (empty) {
+ targetUri = "/";
+ }
+
+ final String baseUri = sourceUri.substring(0, sourceUri.lastIndexOf('/') + 1);
+
+ final Path basePath = new Path(baseUri);
+ final Path targetPath = new Path(targetUri);
+
+ while (!basePath.isEmpty() && targetPath.size() > 1
+ && basePath.first().equals(targetPath.first())) {
+ targetPath.removeFirst();
+ }
+
+ String prefix = basePath.isEmpty() ? "" : generateUpDots(basePath.getSteps().size() - 1);
+
+ String targetString = prefix + targetPath;
+ if (empty) {
+ if (!targetString.endsWith("/")) {
+ throw new IllegalStateException("Target URI " + targetString
+ + " doesn't end with a slash!");
+ }
+ targetString = targetString.substring(0, targetString.length() - 1);
+ }
+
+ try {
+ return new URI(targetString).normalize().toString();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected static String getLastStep(String url) {
+ return url.substring(url.lastIndexOf("/") + 1);
+ }
+
+ protected static String generateUpDots(int length) {
+ if (length == 0) {
+ return "./";
+ }
+ final String[] upDotsArray = new String[length];
+ Arrays.fill(upDotsArray, "..");
+ return StringUtil.join(upDotsArray, "/") + (upDotsArray.length == 0 ? "" : "/");
+ }
+
+ protected static class Path {
+
+ private List<String> steps = new ArrayList<String>();
+
+ public Path(final String path) {
+ if (!path.startsWith("/")) {
+ throw new IllegalArgumentException("Path " + path + " must start with a slash.");
+ }
+ this.steps.addAll(Arrays.asList(path.substring(1).split("/", -1)));
+ }
+
+ public int size() {
+ return this.steps.size();
+ }
+
+ public String removeFirst() {
+ return this.steps.remove(0);
+ }
+
+ public String toString() {
+ return StringUtil.join(this.steps.toArray(new String[this.steps.size()]), "/");
+ }
+
+ public String debug() {
+ final StringBuffer buf = new StringBuffer();
+ for (final String step : this.steps) {
+ buf.append("[" + step + "]");
+ }
+ return buf.toString();
+ }
+
+ public List<String> getSteps() {
+ return Collections.unmodifiableList(this.steps);
+ }
+
+ public boolean isEmpty() {
+ return this.steps.isEmpty();
+ }
+
+ public String first() {
+ return this.steps.get(0);
+ }
+
+ public String last() {
+ return this.steps.get(this.steps.size() - 1);
+ }
+
+ }
+
+}
Modified: lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/OutgoingLinkRewriterTest.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/OutgoingLinkRewriterTest.java?rev=1054381&r1=1054380&r2=1054381&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/OutgoingLinkRewriterTest.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/OutgoingLinkRewriterTest.java Sun Jan 2 10:32:43 2011
@@ -23,26 +23,32 @@ import org.apache.lenya.cms.repository.S
public class OutgoingLinkRewriterTest extends AbstractAccessControlTest {
public void testRelativeUrls() throws Exception {
- Session session = login("lenya");
- String url = "/aaa/bbb/ccc";
+ final Session session = login("lenya");
+ final String url = "/aaa/bbb/ccc";
boolean ssl = false;
boolean considerSslPolicies = false;
- boolean relativeUrls = true;
- OutgoingLinkRewriter rewriter = new OutgoingLinkRewriter(getManager(), session, url, ssl,
- considerSslPolicies, relativeUrls);
+ final OutgoingLinkRewriter relativeRewriter = new OutgoingLinkRewriter(getManager(),
+ session, url, ssl, considerSslPolicies, true);
+
+ assertEquals(relativeRewriter.rewrite("") + "/index", "../../index");
+ assertEquals(relativeRewriter.rewrite("/aaa/bbb/foo"), "foo");
+ assertEquals(relativeRewriter.rewrite("/aaa/bbb"), "../bbb");
+ assertEquals(relativeRewriter.rewrite("/aaa/bbb/ccc/ddd"), "ccc/ddd");
+ assertEquals(relativeRewriter.rewrite("/aaa/foo"), "../foo");
+ assertEquals(relativeRewriter.rewrite("/aaa/foo/bar"), "../foo/bar");
+ assertEquals(relativeRewriter.rewrite("/foo/bar"), "../../foo/bar");
+ assertEquals(relativeRewriter.rewrite("/aaa/foo/bar/baz"), "../foo/bar/baz");
+ assertEquals(relativeRewriter.rewrite("/aaa/bbb/?hello"), "?hello");
+ assertEquals(relativeRewriter.rewrite("/aaa/?hello"), "../?hello");
+ assertEquals(relativeRewriter.rewrite("/?hello"), "../../?hello");
+
+ final OutgoingLinkRewriter absoluteRewriter = new OutgoingLinkRewriter(getManager(),
+ session, url, ssl, considerSslPolicies, false);
+
+ assertEquals(absoluteRewriter.rewrite("") + "/index", "/index");
- assertEquals(rewriter.rewrite("/aaa/bbb/foo"), "foo");
- assertEquals(rewriter.rewrite("/aaa/bbb"), "..");
- assertEquals(rewriter.rewrite("/aaa/bbb/ccc/ddd"), "ccc/ddd");
- assertEquals(rewriter.rewrite("/aaa/foo"), "../foo");
- assertEquals(rewriter.rewrite("/aaa/foo/bar"), "../foo/bar");
- assertEquals(rewriter.rewrite("/foo/bar"), "../../foo/bar");
- assertEquals(rewriter.rewrite("/aaa/foo/bar/baz"), "../foo/bar/baz");
- assertEquals(rewriter.rewrite("/aaa/bbb/?hello"), "../bbb/?hello");
- assertEquals(rewriter.rewrite("/aaa/?hello"), "../?hello");
- assertEquals(rewriter.rewrite("/?hello"), "../../?hello");
}
}
Added: lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/UriUtilTest.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/UriUtilTest.java?rev=1054381&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/UriUtilTest.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/modules-core/linking/java/test/org/apache/lenya/cms/linking/UriUtilTest.java Sun Jan 2 10:32:43 2011
@@ -0,0 +1,43 @@
+package org.apache.lenya.cms.linking;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import junit.framework.TestCase;
+
+import org.apache.lenya.cms.linking.UriUtil;
+
+public class UriUtilTest extends TestCase {
+
+ public void testRelativePath() throws URISyntaxException {
+
+ final String baseUri = "/aaa/bbb/";
+
+ verify(baseUri, "/aaa/bbb/ccc", "ccc");
+ verify(baseUri, "/aaa/bbb", "../bbb");
+ verify(baseUri, "/aaa/bbb/", "");
+ verify(baseUri, "/aaa", "../../aaa");
+ verify(baseUri, "/aaa/", "../");
+ verify(baseUri, "/", "../../");
+ verify(baseUri, "/aaa/bbb/foo", "foo");
+ verify(baseUri, "/aaa/bbb/ccc/ddd", "ccc/ddd");
+ verify(baseUri, "/aaa/foo", "../foo");
+ verify(baseUri, "/aaa/foo/bar", "../foo/bar");
+ verify(baseUri, "/foo/bar", "../../foo/bar");
+ verify(baseUri, "/aaa/foo/bar/baz", "../foo/bar/baz");
+ verify(baseUri, "/aaa/bbb/?hello", "?hello");
+ verify(baseUri, "/aaa/?hello", "../?hello");
+ verify(baseUri, "/?hello", "../../?hello");
+
+ assertEquals("../..", UriUtil.getRelativeUri(baseUri, ""));
+ }
+
+ protected void verify(final String base, final String target, final String rel) throws URISyntaxException {
+ final String resolvedRel = UriUtil.getRelativeUri(base, target);
+ assertEquals(rel, resolvedRel);
+ final String prefix = "http://foo.com";
+ final URI baseUri = new URI(prefix + base);
+ assertEquals(prefix + target, baseUri.resolve(resolvedRel).toString());
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org