Index: src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java =================================================================== --- src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java (revision 536107) +++ src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java (working copy) @@ -18,10 +18,14 @@ package org.apache.lenya.cms.cocoon.transformation; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.service.ServiceException; import org.apache.avalon.framework.service.ServiceSelector; @@ -47,6 +51,7 @@ import org.apache.lenya.cms.repository.Session; import org.apache.lenya.util.Query; import org.apache.lenya.util.ServletHelper; +import org.apache.lenya.util.StringUtil; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; @@ -99,6 +104,8 @@ private DocumentFactory factory; private LinkResolver linkResolver; private String contextPath; + + private boolean relativeUrls = false; /** * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, @@ -155,6 +162,24 @@ } } + public void configure(Configuration config) throws ConfigurationException { + super.configure(config); + Configuration urlConfig = config.getChild("urls", false); + if (urlConfig != null) { + String value = urlConfig.getAttribute("type"); + if (value.equals("relative")) { + this.relativeUrls = true; + } + else if (value.equals("absolute")) { + this.relativeUrls = false; + } + else { + throw new ConfigurationException("Invalid URL type [" + value + + "], must be relative or absolute."); + } + } + } + /** * Returns the currently processed document. * @@ -330,17 +355,27 @@ throws AccessControlException { String webappUrl = targetDocument.getCanonicalWebappURL(); - Policy policy = this.policyManager.getPolicy(this.accreditableManager, webappUrl); - - Proxy proxy = targetDocument.getPublication().getProxy(targetDocument, - policy.isSSLProtected()); - + String rewrittenURL; - if (proxy == null) { - rewrittenURL = this.request.getContextPath() + webappUrl; - } else { - rewrittenURL = proxy.getURL(targetDocument); + if (this.relativeUrls) { + rewrittenURL = getRelativeUrlTo(webappUrl); } + else { + Policy policy = this.policyManager.getPolicy(this.accreditableManager, webappUrl); + + Proxy proxy = targetDocument.getPublication().getProxy(targetDocument, + policy.isSSLProtected()); + + if (proxy == null) { + rewrittenURL = this.request.getContextPath() + webappUrl; + } else { + rewrittenURL = proxy.getURL(targetDocument); + } + if (getLogger().isDebugEnabled()) { + getLogger().debug(this.indent + "SSL protection: [" + policy.isSSLProtected() + "]"); + getLogger().debug(this.indent + "Resolved proxy: [" + proxy + "]"); + } + } int lastDotIndex = rewrittenURL.lastIndexOf("."); if (lastDotIndex > -1) { @@ -356,14 +391,42 @@ } if (getLogger().isDebugEnabled()) { - getLogger().debug(this.indent + "SSL protection: [" + policy.isSSLProtected() + "]"); - getLogger().debug(this.indent + "Resolved proxy: [" + proxy + "]"); getLogger().debug(this.indent + "Rewriting URL to: [" + rewrittenURL + "]"); } setAttribute(newAttrs, attributeName, rewrittenURL); } + private String getRelativeUrlTo(String webappUrl) { + String currentUrl = this.currentDocument.getCanonicalWebappURL(); + List sourceSteps = toList(currentUrl); + List targetSteps = toList(webappUrl); + + while (!sourceSteps.isEmpty() && !targetSteps.isEmpty() + && sourceSteps.get(0).equals(targetSteps.get(0))) { + sourceSteps.remove(0); + targetSteps.remove(0); + } + + String upDots = ""; + if (sourceSteps.size() > 1) { + String[] upDotsArray = new String[sourceSteps.size() - 1]; + Arrays.fill(upDotsArray, ".."); + upDots = StringUtil.join(upDotsArray, "/") + "/"; + } + + String[] targetArray = (String[]) targetSteps.toArray(new String[targetSteps.size()]); + String targetPath = StringUtil.join(targetArray, "/"); + + String relativeUrl = upDots + targetPath; + return relativeUrl; + + } + + protected List toList(String url) { + return new ArrayList(Arrays.asList(url.substring(1).split("/"))); + } + /** * Sets the value of the href attribute. *