diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/mapper/Converter.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/mapper/Converter.java index a75d652a..c6096360 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/mapper/Converter.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/mapper/Converter.java @@ -10,6 +10,7 @@ import au.org.aodn.ogcapi.server.core.parser.stac.GeometryVisitor; import au.org.aodn.ogcapi.server.core.util.ConstructUtils; import au.org.aodn.ogcapi.server.core.util.GeometryUtils; +import au.org.aodn.ogcapi.server.core.util.LinkUtils; import lombok.Builder; import lombok.Getter; import lombok.Setter; @@ -116,6 +117,7 @@ default Collection getCollection(D m, Filter fil .type(l.getType()) .rel(l.getRel()) .title(l.getTitle()) + .description(l.getDescription()) .aiGroup(l.getAiGroup()) ) .toList() diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/ExtendedLink.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/ExtendedLink.java index 64cdb612..1dce4263 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/ExtendedLink.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/ExtendedLink.java @@ -12,6 +12,9 @@ public class ExtendedLink extends Link { @JsonProperty("ai:group") private String aiGroup; + @JsonProperty("description") + private String description; + public ExtendedLink() { super(); } @@ -21,6 +24,11 @@ public ExtendedLink aiGroup(String aiGroup) { return this; } + public ExtendedLink description(String description) { + this.description = description; + return this; + } + @Override public ExtendedLink href(String href) { super.href(href); diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/LinkModel.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/LinkModel.java index 67bbae08..083cdce2 100644 --- a/server/src/main/java/au/org/aodn/ogcapi/server/core/model/LinkModel.java +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/model/LinkModel.java @@ -1,5 +1,6 @@ package au.org.aodn.ogcapi.server.core.model; +import au.org.aodn.ogcapi.server.core.util.LinkUtils; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -18,4 +19,15 @@ public class LinkModel { @JsonProperty("ai:group") protected String aiGroup; + + @JsonProperty("description") + protected String description; + + public void setTitle(String title) { + String[] parsed = LinkUtils.parseLinkTitleDescription(title); + this.title = parsed[0]; + if (this.description == null) { + this.description = parsed[1]; + } + } } diff --git a/server/src/main/java/au/org/aodn/ogcapi/server/core/util/LinkUtils.java b/server/src/main/java/au/org/aodn/ogcapi/server/core/util/LinkUtils.java new file mode 100644 index 00000000..217e4c85 --- /dev/null +++ b/server/src/main/java/au/org/aodn/ogcapi/server/core/util/LinkUtils.java @@ -0,0 +1,29 @@ +package au.org.aodn.ogcapi.server.core.util; + +public class LinkUtils { + public static String[] parseLinkTitleDescription(String combinedTitle) { + // if combinedTitle is null, return null for both title and description + if (combinedTitle == null) { + return new String[]{null, null}; + } + // Otherwise, find the last bracket + int bracketCount = 0; + for (int i = combinedTitle.length() - 1; i >= 0; i--) { + if (combinedTitle.charAt(i) == ']') { + bracketCount++; + } else if (combinedTitle.charAt(i) == '[') { + bracketCount--; + if (bracketCount == 0) { + String title = combinedTitle.substring(0, i).trim(); + String description = combinedTitle.substring(i + 1, combinedTitle.length() - 1).trim(); + return new String[]{ + title, + description.isEmpty() ? null : description + }; + } + } + } + // return null description if no matching bracket found + return new String[]{combinedTitle, null}; + } +} diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/mapper/StacToCollectionTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/mapper/StacToCollectionTest.java index 76908460..26ec9290 100644 --- a/server/src/test/java/au/org/aodn/ogcapi/server/core/mapper/StacToCollectionTest.java +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/mapper/StacToCollectionTest.java @@ -81,6 +81,7 @@ public void verifyAddingPropertyWorks() { .type("text/html") .title("Data Link") .aiGroup("data-access") + .description("description") .build(); var link2 = LinkModel.builder() .rel("self") @@ -88,6 +89,7 @@ public void verifyAddingPropertyWorks() { .type("application/json") .title("Self Link") .aiGroup("ai-group") + .description("description") .build(); var theme = ThemeModel.builder() .scheme("scheme") diff --git a/server/src/test/java/au/org/aodn/ogcapi/server/core/util/LinkUtilsTest.java b/server/src/test/java/au/org/aodn/ogcapi/server/core/util/LinkUtilsTest.java new file mode 100644 index 00000000..791e79d0 --- /dev/null +++ b/server/src/test/java/au/org/aodn/ogcapi/server/core/util/LinkUtilsTest.java @@ -0,0 +1,54 @@ +package au.org.aodn.ogcapi.server.core.util; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class LinkUtilsTest { + @Test + void testParseLinkTitleDescription_normalCase() { + String[] result = LinkUtils.parseLinkTitleDescription("mnf:adcp_public_data[ADCP data for Southern Surveyor Voyage SS 09/2003]"); + + assertEquals("mnf:adcp_public_data", result[0]); + assertEquals("ADCP data for Southern Surveyor Voyage SS 09/2003", result[1]); + } + + @Test + void testParseLinkTitleDescription_emptyDescription() { + String[] result = LinkUtils.parseLinkTitleDescription("Ocean Radar page on IMOS website[]"); + + assertEquals("Ocean Radar page on IMOS website", result[0]); + assertNull(result[1]); + } + + @Test + void testParseLinkTitleDescription_titleWithBrackets() { + String[] result = LinkUtils.parseLinkTitleDescription("DATA ACCESS - GBR10 benthic habitat type [Geotiff direct download][]"); + + assertEquals("DATA ACCESS - GBR10 benthic habitat type [Geotiff direct download]", result[0]); + assertNull(result[1]); + } + + @Test + void testParseLinkTitleDescription_emptyTitleAndDescription() { + String[] result = LinkUtils.parseLinkTitleDescription(null); + + assertNull(result[0]); + assertNull(result[1]); + } + + @Test + void testParseLinkTitleDescription_multipleNestedBrackets() { + String[] result = LinkUtils.parseLinkTitleDescription("Title [level1 [level2]] [Final Description]"); + + assertEquals("Title [level1 [level2]]", result[0]); + assertEquals("Final Description", result[1]); + } + + @Test + void testParseLinkTitleDescription_whitespaceOnlyDescription() { + String[] result = LinkUtils.parseLinkTitleDescription("Title[ ]"); + + assertEquals("Title", result[0]); + assertNull(result[1]); + } +}