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 2008/03/07 00:55:43 UTC
svn commit: r634466 - in /lenya/trunk/src/modules-core/linking:
config/sitemap/ java/src/org/apache/lenya/cms/cocoon/transformation/
java/src/org/apache/lenya/cms/linking/
Author: andreas
Date: Thu Mar 6 15:55:37 2008
New Revision: 634466
URL: http://svn.apache.org/viewvc?rev=634466&view=rev
Log:
Refactoring: Extract uuid2url functionality from transformer to rewriter. Add message attribute for all link transformers.
Added:
lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UuidToUrlRewriter.java
Modified:
lenya/trunk/src/modules-core/linking/config/sitemap/transformers.xmap
lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/AbstractLinkTransformer.java
lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java
Modified: lenya/trunk/src/modules-core/linking/config/sitemap/transformers.xmap
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/linking/config/sitemap/transformers.xmap?rev=634466&r1=634465&r2=634466&view=diff
==============================================================================
--- lenya/trunk/src/modules-core/linking/config/sitemap/transformers.xmap (original)
+++ lenya/trunk/src/modules-core/linking/config/sitemap/transformers.xmap Thu Mar 6 15:55:37 2008
@@ -29,6 +29,7 @@
<transform namespace="http://www.w3.org/1999/xhtml" element="form" attribute="action"/>
<transform namespace="http://www.w3.org/1999/xhtml" element="script" attribute="src"/>
<transform namespace="http://www.w3.org/1999/xhtml" element="input" attribute="src"/>
+ <markBrokenLinks attribute="class" value="brokenlink" messageAttribute="title"/>
</map:transformer>
<map:transformer name="url2uuid" logger="lenya.sitemap.transformer.url2uuid"
Modified: lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/AbstractLinkTransformer.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/AbstractLinkTransformer.java?rev=634466&r1=634465&r2=634466&view=diff
==============================================================================
--- lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/AbstractLinkTransformer.java (original)
+++ lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/AbstractLinkTransformer.java Thu Mar 6 15:55:37 2008
@@ -17,6 +17,7 @@
*/
package org.apache.lenya.cms.cocoon.transformation;
+import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -27,9 +28,17 @@
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.transformation.AbstractSAXTransformer;
import org.apache.lenya.ac.AccessControlException;
import org.apache.lenya.cms.linking.LinkRewriter;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.publication.URLInformation;
+import org.apache.lenya.util.ServletHelper;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -41,18 +50,29 @@
* </p>
* <p>
* If the link rewriter returns <code>null</code> for a link, an attribute can be
- * added to the corresponding element.
+ * added to the corresponding element, with an optional message of the form "Broken link: ...".
* </p>
* <code><pre>
* <map:transformer ... >
* <transform namespace="http://www.w3.org/1999/xhtml" element="a" attribute="href"/>
* <transform namespace="..." ... />
- * <markBrokenLinks attribute="..." value="..."/>
+ * <markBrokenLinks attribute="..." value="..." messageAttribute="..."/>
* </map:transformer>
* </pre></code>
*/
public abstract class AbstractLinkTransformer extends AbstractSAXTransformer {
+ private String area;
+
+ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters params)
+ throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, src, params);
+ Request request = ObjectModelHelper.getRequest(objectModel);
+ String webappUrl = ServletHelper.getWebappURI(request);
+ URLInformation url = new URLInformation(webappUrl);
+ this.area = url.getArea();
+ }
+
/**
* Set of supported local names for quick pre-checks.
*/
@@ -61,6 +81,7 @@
private boolean markBrokenLinks;
private String brokenLinkAttribute;
private String brokenLinkValue;
+ private String brokenLinkMessageAttribute;
public void configure(Configuration config) throws ConfigurationException {
super.configure(config);
@@ -84,6 +105,10 @@
if (brokenLinksConfig != null) {
this.brokenLinkAttribute = brokenLinksConfig.getAttribute("attribute");
this.brokenLinkValue = brokenLinksConfig.getAttribute("value");
+ String messageAttr = brokenLinksConfig.getAttribute("messageAttribute", null);
+ if (messageAttr != null) {
+ this.brokenLinkMessageAttribute = messageAttr;
+ }
this.markBrokenLinks = true;
}
else {
@@ -225,7 +250,7 @@
getLogger().debug(this.indent + "ignoreAElement: " + this.ignoreLinkElement);
}
- // use existsMatching to match up with ednElement
+ // use existsMatching to match up with endElement
if (existsMatchingConfiguration(uri,name) && this.useIgnore) {
if(this.ignoreLinkElement) {
ignoreLinkElementStack.push(Boolean.TRUE);
@@ -260,7 +285,12 @@
setAttribute(newAttrs, config.attribute, rewrittenUrl);
}
else {
- markBrokenLink(newAttrs, config.attribute);
+ if (this.area != null && this.area.equals(Publication.LIVE_AREA)) {
+ this.ignoreLinkElement = true;
+ }
+ else {
+ markBrokenLink(newAttrs, config.attribute, linkUrl);
+ }
}
}
}
@@ -313,9 +343,10 @@
* Marks a link element as broken and removes the attribute which contained the URL.
* @param newAttrs The new attributes.
* @param attrName The attribute name containing the URL which could not be rewritten.
+ * @param brokenLinkUri The broken link URI.
* @throws AccessControlException when something went wrong.
*/
- protected void markBrokenLink(AttributesImpl newAttrs, String attrName)
+ protected void markBrokenLink(AttributesImpl newAttrs, String attrName, String brokenLinkUri)
throws AccessControlException {
if (this.markBrokenLinks) {
if (newAttrs.getIndex(this.brokenLinkAttribute) > -1) {
@@ -323,6 +354,15 @@
}
if (newAttrs.getIndex(attrName) > -1) {
newAttrs.setAttribute(newAttrs.getIndex(attrName), "", attrName, attrName, "CDATA", "");
+ }
+ String msgAttr = this.brokenLinkMessageAttribute;
+ if (msgAttr != null) {
+ int index = newAttrs.getIndex(msgAttr);
+ if (index > -1) {
+ newAttrs.removeAttribute(index);
+ }
+ String msg = "Broken link: " + brokenLinkUri;
+ newAttrs.addAttribute("", msgAttr, msgAttr, "CDATA", msg);
}
newAttrs.addAttribute("", this.brokenLinkAttribute, this.brokenLinkAttribute, "CDATA", this.brokenLinkValue);
}
Modified: lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java?rev=634466&r1=634465&r2=634466&view=diff
==============================================================================
--- lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java (original)
+++ lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/cocoon/transformation/UuidToUrlTransformer.java Thu Mar 6 15:55:37 2008
@@ -18,295 +18,53 @@
package org.apache.lenya.cms.cocoon.transformation;
import java.io.IOException;
-import java.io.Serializable;
-import java.net.MalformedURLException;
import java.util.Map;
-import java.util.StringTokenizer;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
-import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.excalibur.source.Source;
-import org.apache.excalibur.source.SourceValidity;
-import org.apache.lenya.ac.AccessControlException;
-import org.apache.lenya.cms.linking.Link;
import org.apache.lenya.cms.linking.LinkResolver;
import org.apache.lenya.cms.linking.LinkRewriter;
-import org.apache.lenya.cms.linking.LinkTarget;
-import org.apache.lenya.cms.publication.Area;
-import org.apache.lenya.cms.publication.Document;
+import org.apache.lenya.cms.linking.UuidToUrlRewriter;
import org.apache.lenya.cms.publication.DocumentFactory;
import org.apache.lenya.cms.publication.DocumentUtil;
-import org.apache.lenya.cms.publication.Publication;
-import org.apache.lenya.cms.publication.URLInformation;
-import org.apache.lenya.cms.repository.RepositoryUtil;
-import org.apache.lenya.cms.repository.Session;
-import org.apache.lenya.util.Query;
import org.apache.lenya.util.ServletHelper;
import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
/**
- * <p>
* UUID to URL transformer.
- * </p>
- *
- * <p>
- * This transformer is applied to an XHMTL document. It processes all links following the
- * {@link LinkResolver} syntax which are configured using <code><transform/></code> elements
- * (see below).
- * </p>
- * <p>
- * These links are resolved using the following rules:
- * </p>
- * <ul>
- * <li>The current area (obtained from the page envelope) is used.</li>
- * <li>A URL prefix is added depending on the proxy configuration of the publication.</li>
- * <li>If the target document does not exist and is in the authoring area, the href attribute is
- * removed and a class="brokenlink" attribute is added to the <code><a/></code> element.</li>
- * <li>If the target document does not exist and is in the live area, the <code><a/></code>
- * element is removed to disable the link.</li>
- * </ul>
- *
- * <p>
- * You can add the query parameter <code>uuid2url.extension</code> to <code>lenya-document:</code>
- * URLs to set a specific link extension.
- * </p>
- * <p>
- * The resulting URLs are absolute web application URLs (without the servlet context path).
- * </p>
+ * @see AbstractLinkTransformer
+ * @see UuidToUrlRewriter
*
* $Id: LinkRewritingTransformer.java,v 1.7 2004/03/16 11:12:16 gregor
*/
-public class UuidToUrlTransformer extends AbstractLinkTransformer implements Disposable, CacheableProcessingComponent {
-
- protected static final String BROKEN_ATTRIB = "class";
- protected static final String BROKEN_VALUE = "brokenlink";
- protected static final String EXTENSION_PARAM = "uuid2url.extension";
+public class UuidToUrlTransformer extends AbstractLinkTransformer implements Disposable {
- private String currentUrl;
-
- private DocumentFactory factory;
+ private UuidToUrlRewriter rewriter;
private LinkResolver linkResolver;
- private Document currentDoc;
- private String cacheKey;
- private SourceValidity validity;
- /**
- * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
- * java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
- */
- public void setup(SourceResolver resolver, Map _objectModel, String _source,
- Parameters _parameters) throws ProcessingException, SAXException, IOException {
- super.setup(resolver, _objectModel, _source, _parameters);
-
- Request _request = ObjectModelHelper.getRequest(_objectModel);
+ public void setup(SourceResolver resolver, Map objectModel, String source,
+ Parameters parameters) throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, source, parameters);
+ Request request = ObjectModelHelper.getRequest(objectModel);
this.useIgnore = true;
- Source source = null;
try {
- Session session = RepositoryUtil.getSession(this.manager, _request);
- this.factory = DocumentUtil.createDocumentFactory(this.manager, session);
- this.currentUrl = ServletHelper.getWebappURI(_request);
- if (this.factory.isDocument(this.currentUrl)) {
- this.currentDoc = this.factory.getFromURL(this.currentUrl);
- }
+ DocumentFactory factory = DocumentUtil.getDocumentFactory(this.manager, request);
+ String currentUrl = ServletHelper.getWebappURI(request);
this.linkResolver = (LinkResolver) this.manager.lookup(LinkResolver.ROLE);
+ this.rewriter = new UuidToUrlRewriter(currentUrl, this.linkResolver, factory);
+
+ if (factory.isDocument(currentUrl)) {
+ this.rewriter.setCurrentDocument(factory.getFromURL(currentUrl));
+ }
- URLInformation info = new URLInformation(this.currentUrl);
- Publication pub = factory.getPublication(info.getPublicationId());
- Area area = pub.getArea(info.getArea());
- this.cacheKey = pub.getId() + ":" + area.getName();
- source = resolver.resolveURI(area.getSite().getRepositoryNode().getSourceURI());
- this.validity = source.getValidity();
} catch (final Exception e) {
throw new ProcessingException(e);
- } finally {
- if (source != null) {
- resolver.release(source);
- }
- }
- }
-
- protected void handleLink(String linkUrl, AttributeConfiguration config, AttributesImpl newAttrs)
- throws Exception {
-
- URLInformation info = new URLInformation(this.currentUrl);
- if (linkUrl.startsWith("lenya-document:")) {
-
- String anchor = null;
- String url = null;
-
- int anchorIndex = linkUrl.indexOf("#");
- if (anchorIndex > -1) {
- url = linkUrl.substring(0, anchorIndex);
- anchor = linkUrl.substring(anchorIndex + 1);
- } else {
- url = linkUrl;
- }
-
- StringTokenizer tokenizer = new StringTokenizer(url, "?");
- String linkUri = tokenizer.nextToken();
- String queryString = null;
- String requiredExtension = null;
- if (tokenizer.hasMoreTokens()) {
- queryString = tokenizer.nextToken();
- Query query = new Query(queryString);
- requiredExtension = query.getValue(EXTENSION_PARAM);
- query.removeValue(EXTENSION_PARAM);
- queryString = query.toString();
- }
-
- LinkTarget target;
- if (this.currentDoc != null) {
- target = this.linkResolver.resolve(this.currentDoc, linkUri);
- } else {
- Link link = getAbsoluteLink(info, linkUri);
- target = this.linkResolver.resolve(this.factory, link.getUri());
- }
-
- if (target.exists() && target.getDocument().hasLink()) {
- Document targetDocument = target.getDocument();
- String extension = getExtension(targetDocument, requiredExtension);
- rewriteLink(newAttrs, config.attribute, targetDocument, anchor, queryString,
- extension);
- } else if (info.getArea().equals(Publication.AUTHORING_AREA)) {
- markBrokenLink(newAttrs, config.attribute, linkUrl);
- } else {
- this.ignoreLinkElement = true;
- }
- } else {
- /*
- * This is legacy code. It rewrites links to non-document images (in resources/shared).
- * These images shouldn't be referenced in documents since this violates the separation
- * between content and layout.
- */
- String prefix = "/" + info.getPublicationId() + "/";
- if (linkUrl.startsWith(prefix)) {
- String pubUrl = linkUrl.substring(prefix.length());
- StringTokenizer tokenizer = new StringTokenizer(pubUrl, "/");
- String area = tokenizer.nextToken();
-
- // don't rewrite /{pub}/modules/...
- if (area.equals(Publication.AUTHORING_AREA)) {
- String areaUrl = pubUrl.substring(area.length());
- String newUrl = prefix + area + areaUrl;
- setAttribute(newAttrs, config.attribute, newUrl);
- }
- }
- }
- }
-
- /**
- * The link is constructed from the linkUri string. If it lacks the area or publication ID
- * information, these are obtained from the current URL information.
- * @param info The current URL information.
- * @param linkUri The link URI to use.
- * @return A link.
- * @throws MalformedURLException if the linkUri parameter is malformed.
- */
- protected Link getAbsoluteLink(URLInformation info, String linkUri)
- throws MalformedURLException {
- Link link = new Link(linkUri);
- if (link.getPubId() == null) {
- link.setPubId(info.getPublicationId());
- }
- if (link.getArea() == null) {
- link.setArea(info.getArea());
- }
- return link;
- }
-
- /**
- * Get the extension of a document. Caution: resolving the extension is expensive!
- * @param targetDocument The document.
- * @param requiredExtension The required extension.
- * @return The required extension or, if it is null, the document's default extension.
- */
- protected String getExtension(Document targetDocument, String requiredExtension) {
- String extension = requiredExtension != null ? requiredExtension : targetDocument.getExtension();
- if (extension.length() > 0) {
- extension = "." + extension;
}
- return extension;
- }
-
- /**
- * Marks a <code><a/></code> element as broken and removes href attribute.
- *
- * @param newAttrs The new attributes.
- * @param attrName The attribute name.
- * @param brokenUrl The broken link URI.
- * @throws AccessControlException when something went wrong.
- */
- protected void markBrokenLink(AttributesImpl newAttrs, String attrName, String brokenUrl)
- throws AccessControlException {
- if (newAttrs.getIndex(BROKEN_ATTRIB) > -1)
- newAttrs.removeAttribute(newAttrs.getIndex(BROKEN_ATTRIB));
- if (newAttrs.getIndex("title") > -1)
- newAttrs.removeAttribute(newAttrs.getIndex("title"));
- if (newAttrs.getIndex(attrName) > -1)
- newAttrs.setAttribute(newAttrs.getIndex(attrName), "", attrName, attrName, "CDATA", "");
- String warning = "Broken Link: " + brokenUrl;
- newAttrs.addAttribute("", "title", "title", "CDATA", warning);
- newAttrs.addAttribute("", BROKEN_ATTRIB, BROKEN_ATTRIB, "CDATA", BROKEN_VALUE);
- }
-
- /**
- * Rewrites a link.
- *
- * @param newAttrs The new attributes.
- * @param attributeName The name of the attribute to rewrite.
- * @param targetDocument The target document.
- * @param anchor The anchor (the string after the # character in the URL).
- * @param queryString The query string without question mark.
- * @param extension The extension to use.
- * @throws AccessControlException when something went wrong.
- */
- protected void rewriteLink(AttributesImpl newAttrs, String attributeName,
- Document targetDocument, String anchor, String queryString, String extension)
- throws AccessControlException {
-
- String webappUrl = targetDocument.getCanonicalWebappURL();
-
- int lastDotIndex = webappUrl.lastIndexOf(".");
- if (lastDotIndex > -1) {
- webappUrl = webappUrl.substring(0, lastDotIndex) + extension;
- }
-
- if (anchor != null) {
- webappUrl += "#" + anchor;
- }
-
- if (queryString != null && queryString.length() > 0) {
- webappUrl += "?" + queryString;
- }
-
- if (getLogger().isDebugEnabled()) {
- getLogger().debug(this.indent + "Rewriting URL to: [" + webappUrl + "]");
- }
-
- setAttribute(newAttrs, attributeName, webappUrl);
- }
-
- /**
- * Sets the value of the href attribute.
- *
- * @param attr The attributes.
- * @param name The attribute name.
- * @param value The value.
- * @throws IllegalArgumentException if the href attribute is not contained in this attributes.
- */
- protected void setAttribute(AttributesImpl attr, String name, String value) {
- int position = attr.getIndex(name);
- if (position == -1) {
- throw new IllegalArgumentException("The href attribute is not available!");
- }
- attr.setValue(position, value);
}
/**
@@ -318,30 +76,8 @@
}
}
- /**
- * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
- */
- public void recycle() {
- this.ignoreLinkElement = false;
- this.currentUrl = null;
- }
-
protected LinkRewriter getLinkRewriter() {
- return null;
- }
-
- public Serializable getKey() {
- if (this.cacheKey == null) {
- throw new IllegalStateException("setup() was not called.");
- }
- return this.cacheKey;
- }
-
- public SourceValidity getValidity() {
- if (this.validity == null) {
- throw new IllegalStateException("setup() was not called.");
- }
- return this.validity;
+ return this.rewriter;
}
}
Added: lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UuidToUrlRewriter.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UuidToUrlRewriter.java?rev=634466&view=auto
==============================================================================
--- lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UuidToUrlRewriter.java (added)
+++ lenya/trunk/src/modules-core/linking/java/src/org/apache/lenya/cms/linking/UuidToUrlRewriter.java Thu Mar 6 15:55:37 2008
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.linking;
+
+import java.net.MalformedURLException;
+import java.util.StringTokenizer;
+
+import org.apache.lenya.ac.AccessControlException;
+import org.apache.lenya.cms.publication.Document;
+import org.apache.lenya.cms.publication.DocumentFactory;
+import org.apache.lenya.cms.publication.Publication;
+import org.apache.lenya.cms.publication.URLInformation;
+import org.apache.lenya.util.Assert;
+import org.apache.lenya.util.Query;
+
+/**
+ * <p>
+ * Rewrite lenya-document: URLs to /{pub}/{area}/... URLs.
+ * </p>
+ * <p>
+ * To support legacy documents, image URLs starting with /{pub}/{area} are also
+ * handled.
+ * </p>
+ * <p>
+ * These links are resolved using the following rules:
+ * </p>
+ * <ul>
+ * <li>The current area (obtained from the page envelope) is used.</li>
+ * <li>A URL prefix is added depending on the proxy configuration of the
+ * publication.</li>
+ * <li>If the target document does not exist and is in the authoring area, the
+ * href attribute is removed and a class="brokenlink" attribute is added to the
+ * <code><a/></code> element.</li>
+ * <li>If the target document does not exist and is in the live area, the
+ * <code><a/></code> element is removed to disable the link.</li>
+ * </ul>
+ * <p>
+ * You can add the query parameter <code>uuid2url.extension</code> to
+ * <code>lenya-document:</code> URLs to set a specific link extension.
+ * </p>
+ * <p>
+ * The resulting URLs are absolute web application URLs (without the servlet
+ * context path).
+ * </p>
+ */
+public class UuidToUrlRewriter implements LinkRewriter {
+
+ protected static final String EXTENSION_PARAM = "uuid2url.extension";
+
+ private String currentUrl;
+ private Document currentDoc;
+ private LinkResolver linkResolver;
+ private DocumentFactory factory;
+
+ /**
+ * @param currentUrl The current request URL.
+ * @param linkResolver The link resolver to use.
+ * @param factory The document factory to use.
+ */
+ public UuidToUrlRewriter(String currentUrl, LinkResolver linkResolver, DocumentFactory factory) {
+ Assert.notNull("current URL", currentUrl);
+ Assert.notNull("link resolver", linkResolver);
+ Assert.notNull("document factory", factory);
+ this.currentUrl = currentUrl;
+ this.factory = factory;
+ this.linkResolver = linkResolver;
+ }
+
+ public void setCurrentDocument(Document doc) {
+ Assert.notNull("current document", doc);
+ this.currentDoc = doc;
+ }
+
+ protected static final String SCHEME = "lenya-document:";
+
+ public boolean matches(String url) {
+ return url.startsWith(SCHEME) || url.startsWith("/");
+ }
+
+ public String rewrite(String linkUrl) {
+
+ String rewrittenUrl = null;
+
+ URLInformation info = new URLInformation(this.currentUrl);
+ if (linkUrl.startsWith(SCHEME)) {
+
+ String anchor = null;
+ String url = null;
+
+ int anchorIndex = linkUrl.indexOf("#");
+ if (anchorIndex > -1) {
+ url = linkUrl.substring(0, anchorIndex);
+ anchor = linkUrl.substring(anchorIndex + 1);
+ } else {
+ url = linkUrl;
+ }
+
+ StringTokenizer tokenizer = new StringTokenizer(url, "?");
+ String linkUri = tokenizer.nextToken();
+ String queryString = null;
+ String requiredExtension = null;
+ if (tokenizer.hasMoreTokens()) {
+ queryString = tokenizer.nextToken();
+ Query query = new Query(queryString);
+ requiredExtension = query.getValue(EXTENSION_PARAM);
+ query.removeValue(EXTENSION_PARAM);
+ queryString = query.toString();
+ }
+
+ LinkTarget target;
+ try {
+ if (this.currentDoc != null) {
+ target = this.linkResolver.resolve(this.currentDoc, linkUri);
+ } else {
+ Link link = getAbsoluteLink(info, linkUri);
+ target = this.linkResolver.resolve(this.factory, link.getUri());
+ }
+
+ if (target.exists() && target.getDocument().hasLink()) {
+ Document targetDocument = target.getDocument();
+ String extension = getExtension(targetDocument, requiredExtension);
+ rewrittenUrl = getWebappUrl(targetDocument, anchor, queryString, extension);
+ } else {
+ rewrittenUrl = null;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ /*
+ * This is legacy code. It rewrites links to non-document images (in
+ * resources/shared). These images shouldn't be referenced in
+ * documents since this violates the separation between content and
+ * layout.
+ */
+ String prefix = "/" + info.getPublicationId() + "/";
+ if (linkUrl.startsWith(prefix)) {
+ String pubUrl = linkUrl.substring(prefix.length());
+ StringTokenizer tokenizer = new StringTokenizer(pubUrl, "/");
+ String area = tokenizer.nextToken();
+
+ // don't rewrite /{pub}/modules/...
+ if (area.equals(Publication.AUTHORING_AREA)) {
+ String areaUrl = pubUrl.substring(area.length());
+ rewrittenUrl = prefix + area + areaUrl;
+ }
+ }
+ if (rewrittenUrl == null) {
+ rewrittenUrl = linkUrl;
+ }
+ }
+ return rewrittenUrl;
+ }
+
+ /**
+ * Rewrites a link.
+ *
+ * @param targetDocument The target document.
+ * @param anchor The anchor (the string after the # character in the URL).
+ * @param queryString The query string without question mark.
+ * @param extension The extension to use.
+ * @return a web application URL.
+ * @throws AccessControlException when something went wrong.
+ */
+ protected String getWebappUrl(Document targetDocument, String anchor, String queryString,
+ String extension) throws AccessControlException {
+
+ String webappUrl = targetDocument.getCanonicalWebappURL();
+
+ int lastDotIndex = webappUrl.lastIndexOf(".");
+ if (lastDotIndex > -1) {
+ webappUrl = webappUrl.substring(0, lastDotIndex) + extension;
+ }
+
+ if (anchor != null) {
+ webappUrl += "#" + anchor;
+ }
+
+ if (queryString != null && queryString.length() > 0) {
+ webappUrl += "?" + queryString;
+ }
+
+ return webappUrl;
+ }
+
+ /**
+ * The link is constructed from the linkUri string. If it lacks the area or
+ * publication ID information, these are obtained from the current URL
+ * information.
+ *
+ * @param info The current URL information.
+ * @param linkUri The link URI to use.
+ * @return A link.
+ * @throws MalformedURLException if the linkUri parameter is malformed.
+ */
+ protected Link getAbsoluteLink(URLInformation info, String linkUri)
+ throws MalformedURLException {
+ Link link = new Link(linkUri);
+ if (link.getPubId() == null) {
+ link.setPubId(info.getPublicationId());
+ }
+ if (link.getArea() == null) {
+ link.setArea(info.getArea());
+ }
+ return link;
+ }
+
+ /**
+ * Get the extension of a document. Caution: resolving the extension is
+ * expensive!
+ *
+ * @param targetDocument The document.
+ * @param requiredExtension The required extension.
+ * @return The required extension or, if it is null, the document's default
+ * extension.
+ */
+ protected String getExtension(Document targetDocument, String requiredExtension) {
+ String extension = requiredExtension != null ? requiredExtension : targetDocument
+ .getExtension();
+ if (extension.length() > 0) {
+ extension = "." + extension;
+ }
+ return extension;
+ }
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@lenya.apache.org
For additional commands, e-mail: commits-help@lenya.apache.org