Skip to content

Commit

Permalink
LinkHandler: Build anchor markup on-demand based on the current statu…
Browse files Browse the repository at this point in the history
…s of link when the anchor is requested. This allows to react on results of link post processors, and avoids building the anchor if not required.
  • Loading branch information
stefanseifert committed Dec 9, 2022
1 parent 48318b4 commit f96a0f1
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 14 deletions.
3 changes: 3 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
<action type="update" dev="sseifert">
LinkType: Mark getEditComponentResourceType and hasRichTextPlugin to be ignored in JSON representation.
</action>
<action type="update" dev="sseifert">
LinkHandler: Build anchor markup on-demand based on the current status of link when the anchor is requested. This allows to react on results of link post processors, and avoids building the anchor if not required.
</action>
<action type="update" dev="sseifert">
Switch to AEM 6.5.7 as minimum version.
</action>
Expand Down
23 changes: 19 additions & 4 deletions src/main/java/io/wcm/handler/link/Link.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
Expand Down Expand Up @@ -54,6 +55,7 @@ public final class Link {
private @NotNull LinkRequest linkRequest;
private boolean linkReferenceInvalid;
private Anchor anchor;
private Function<Link, Anchor> anchorBuilder;
private String url;
private Page targetPage;
private Asset targetAsset;
Expand Down Expand Up @@ -113,6 +115,10 @@ public void setLinkReferenceInvalid(boolean linkReferenceInvalid) {
*/
@JsonIgnore
public Anchor getAnchor() {
if (this.anchor == null && this.anchorBuilder != null) {
this.anchor = this.anchorBuilder.apply(this);
this.anchorBuilder = null;
}
return this.anchor;
}

Expand All @@ -122,11 +128,12 @@ public Anchor getAnchor() {
@JsonIgnore
@SuppressWarnings("java:S1168")
public Map<String, String> getAnchorAttributes() {
if (getAnchor() == null) {
Anchor a = getAnchor();
if (a == null) {
return null;
}
Map<String, String> attributes = new HashMap<>();
for (Attribute attribute : getAnchor().getAttributes()) {
for (Attribute attribute : a.getAttributes()) {
attributes.put(attribute.getName(), attribute.getValue());
}
return attributes;
Expand All @@ -139,13 +146,21 @@ public void setAnchor(Anchor anchor) {
this.anchor = anchor;
}

/**
* @param anchorBuilder Function that builds an anchor representation on demand
*/
public void setAnchorBuilder(Function<Link, Anchor> anchorBuilder) {
this.anchorBuilder = anchorBuilder;
}

/**
* @return Link markup (only the opening anchor tag) or null if resolving was not successful.
*/
@JsonIgnore
public String getMarkup() {
if (this.anchor != null) {
return StringUtils.removeEnd(this.anchor.toString(), "</a>");
Anchor a = getAnchor();
if (a != null) {
return StringUtils.removeEnd(a.toString(), "</a>");
}
else {
return null;
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/io/wcm/handler/link/impl/LinkHandlerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,15 @@ Link processRequest(@NotNull LinkRequest linkRequest) {
// generate markup (if markup builder is available) - first accepting wins
List<Class<? extends LinkMarkupBuilder>> linkMarkupBuilders = linkHandlerConfig.getMarkupBuilders();
if (linkMarkupBuilders != null) {
for (Class<? extends LinkMarkupBuilder> linkMarkupBuilderClass : linkMarkupBuilders) {
LinkMarkupBuilder linkMarkupBuilder = AdaptTo.notNull(adaptable, linkMarkupBuilderClass);
if (linkMarkupBuilder.accepts(link)) {
link.setAnchor(linkMarkupBuilder.build(link));
break;
link.setAnchorBuilder(l -> {
for (Class<? extends LinkMarkupBuilder> linkMarkupBuilderClass : linkMarkupBuilders) {
LinkMarkupBuilder linkMarkupBuilder = AdaptTo.notNull(adaptable, linkMarkupBuilderClass);
if (linkMarkupBuilder.accepts(l)) {
return linkMarkupBuilder.build(l);
}
}
}
return null;
});
}

// postprocess link after resolving
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/io/wcm/handler/link/LinkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ void testAnchor() {
assertEquals("<a href=\"http://dummy\">", underTest.getMarkup());
}

@Test
void testAnchorBuilder() {
assertNull(underTest.getAnchorAttributes());
assertNull(underTest.getMarkup());

underTest.setAnchorBuilder(l -> new Anchor(l.getUrl()).setTitle("title1"));
underTest.setUrl("http://dummy1");

assertEquals("title1", underTest.getAnchor().getTitle());
assertEquals("http://dummy1", underTest.getAnchorAttributes().get("href"));
assertEquals("<a href=\"http://dummy1\" title=\"title1\">", underTest.getMarkup());
}

@Test
void testUrlAndValid() {
assertFalse(underTest.isValid());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void testPipelining() {
assertEquals(true, link.isValid());
assertEquals("http://xyz/path1/pre1/post1", link.getUrl());
assertNotNull(link.getAnchor());
assertEquals("http://xyz/path1/pre1", link.getAnchor().getHRef());
assertEquals("http://xyz/path1/pre1/post1", link.getAnchor().getHRef());
}

@Test
Expand Down Expand Up @@ -138,7 +138,7 @@ void testLinkTargetUrlFallbackProperty() {
assertEquals(true, link.isValid());
assertEquals("http://xyz/fallbackpath1/post1", link.getUrl());
assertNotNull(link.getAnchor());
assertEquals(ImmutableMap.of("href", "http://xyz/fallbackpath1", "target", "_blank"), link.getAnchorAttributes());
assertEquals(ImmutableMap.of("href", "http://xyz/fallbackpath1/post1", "target", "_blank"), link.getAnchorAttributes());
}

@Test
Expand All @@ -158,7 +158,7 @@ void testLinkTargetUrlFallbackProperty_MultipleProperties() {
assertEquals(true, link.isValid());
assertEquals("http://xyz/fallbackpath1/post1", link.getUrl());
assertNotNull(link.getAnchor());
assertEquals(ImmutableMap.of("href", "http://xyz/fallbackpath1"), link.getAnchorAttributes());
assertEquals(ImmutableMap.of("href", "http://xyz/fallbackpath1/post1"), link.getAnchorAttributes());
}

@Test
Expand All @@ -180,7 +180,7 @@ void testLinkTargetUrlFallbackProperty_IgnoreWhenValidLinkSet() {
assertEquals(true, link.isValid());
assertEquals("http://xyz/path1/pre1/post1", link.getUrl());
assertNotNull(link.getAnchor());
assertEquals("http://xyz/path1/pre1", link.getAnchor().getHRef());
assertEquals("http://xyz/path1/pre1/post1", link.getAnchor().getHRef());
}

@Test
Expand Down

0 comments on commit f96a0f1

Please sign in to comment.