Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkImpl: avoid redundant repository lookups #2453

Merged
merged 3 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
package com.adobe.cq.wcm.core.components.internal.link;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -145,16 +144,41 @@ public LinkBuilderImpl(String url, SlingHttpServletRequest req, List<PathProcess
linkUrl = targetAsset.getPath();
}

Asset asset = getAsset(linkUrl);
Page page = getPage(linkUrl).orElse(null);
// linkUrl can be also set via the linkConfiguration, so we have to resolve it from the generic
// resource as well; but try to avoid duplicate resolutions as much as possible.
Asset asset = null;
Page page = null;

if (targetAsset != null) {
asset = targetAsset;
} else if (targetPage != null) {
page = targetPage;
} else {
asset = getAsset(linkUrl);
page = getPage(linkUrl).orElse(null);
}

boolean isExternalUrl = false;
if (asset != null) {
this.reference = asset;
} else if (page != null) {
Pair<Page, String> pair = resolvePage(page);
this.reference = pair.getLeft();
linkUrl = StringUtils.isNotEmpty(pair.getRight()) ? pair.getRight() : linkUrl;

// resolvePage() can resolve the linkUrl into an external URL; this can happen when
// there is a redirect from the page to an external URL; in this case
// the pair is not equivalent
isExternalUrl = !pair.getLeft().getPath().equals(linkUrl);
}
String resolvedLinkURL = validateAndResolveLinkURL(linkUrl);

String resolvedLinkURL = null;
if (this.reference != null && page != null && !isExternalUrl) {
resolvedLinkURL = getPageLinkURL((Page)this.reference);
} else if (StringUtils.isNotEmpty(linkUrl)) {
resolvedLinkURL = linkUrl;
}

Map<String, String> htmlAttributes = mapLinkAttributesToHtml();
return buildLink(resolvedLinkURL, request, htmlAttributes);
}
Expand Down Expand Up @@ -228,34 +252,6 @@ private String validateLinkAttributeValue(@Nullable final String value) {
.orElse(null);
}

/**
* Validates and resolves a link URL.
*
* @param linkURL Link URL
* @return The validated link URL or {@code null} if not valid
*/
@Nullable
private String validateAndResolveLinkURL(@Nullable final String linkURL) {
return Optional.ofNullable(linkURL)
.filter(StringUtils::isNotEmpty)
.map(this::getLinkURL)
.orElse(null);
}

/**
* If the provided {@code path} identifies a {@link Page}, this method will generate the correct URL for the page. Otherwise the
* original {@code String} is returned.
* @param path the page path
*
* @return the URL of the page identified by the provided {@code path}, or the original {@code path} if this doesn't identify a {@link Page}
*/
@NotNull
private String getLinkURL(@NotNull String path) {
return getPage(path)
.map(this::getPageLinkURL)
.orElse(path);
}

/**
* Given a {@link Page}, this method returns the correct URL with the extension
* @param page the page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import com.adobe.cq.wcm.core.components.commons.link.Link;
import com.adobe.cq.wcm.core.components.services.link.PathProcessor;
import com.day.cq.dam.api.Asset;

import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;

Expand Down Expand Up @@ -99,4 +101,20 @@ void testLinkToPage(String given, String expected, String passedDownToPathProces
verify(pathProcessor).externalize(eq(passedDownToPathProcessor), any());
verify(pathProcessor).sanitize(eq(passedDownToPathProcessor), any());
}


void testLinkToAsset() {
Asset asset = context.create().asset("/content/dam/asset.jpg", 0, 0, "image/jpeg");

Link link = new LinkBuilderImpl(asset, context.request(),Collections.singletonList(pathProcessor)).build();
assertEquals("/content/dam/asset.jpg", link.getURL());
assertNotNull(link.getReference());
assertEquals(asset,link.getReference());

link = new LinkBuilderImpl("/content/dam/asset.jpg", context.request(), Collections.singletonList(pathProcessor),false).build();
assertEquals("/content/dam/asset.jpg", link.getURL());
assertEquals("/content/dam/asset.jpg", ((Asset) link.getReference()).getPath());


}
}