1010import org .springframework .stereotype .Service ;
1111import org .springframework .web .reactive .function .server .ServerRequest ;
1212
13+ import java .net .*;
1314import java .util .List ;
1415
1516
@@ -26,7 +27,7 @@ public class LinkGenerator {
2627
2728 private final LinksConfigProps linksConfigProps ;
2829 private static final Link ROOT = new Link ()
29- .href (LinksConfigProps .LINK_PREFIX + "/ stac" )
30+ .href (appendLinkPath ( LinksConfigProps .LINK_PREFIX , " stac") )
3031 .type (MediaType .APPLICATION_JSON_VALUE )
3132 .rel ("root" );
3233
@@ -43,13 +44,11 @@ public void generatePropertyFieldLinks(ServerRequest request, CollectionMetadata
4344
4445 String self = getSelfString (request );
4546
46- // don't want to add double slashes
47- String separator = self .endsWith ("/" ) ? "" : "/" ;
4847
4948 for (PropertyField property : remainingProperties ) {
5049 collection .getLinks ().add (
5150 new Link ()
52- .href (self + separator + property .getJsonName ())
51+ .href (appendLinkPath ( self , property .getJsonName () ))
5352 .type (MediaType .APPLICATION_JSON_VALUE )
5453 .rel ("child" ));
5554 }
@@ -60,7 +59,7 @@ public void generatePropertyFieldLinks(ServerRequest request, CollectionMetadata
6059 .type (MediaType .APPLICATION_JSON_VALUE )
6160 .rel ("self" ));
6261 collection .getLinks ().add (new Link ()
63- .href (self + separator + "items" )
62+ .href (appendLinkPath ( self , "items" ) )
6463 .type (MediaType .APPLICATION_JSON_VALUE )
6564 .rel ("items" ));
6665 collection .getLinks ().add (new Link ()
@@ -77,10 +76,9 @@ public void generatePropertyFieldLinks(ServerRequest request, CollectionMetadata
7776 * @param values A list of unique values in the database for the selected subcataloged field
7877 */
7978 public void generatePropertyValueLinks (ServerRequest request , CollectionMetadata collection , List <String > values ) {
80- String separator = request .path ().endsWith ("/" ) ? "" : "/" ;
8179 values .forEach (value -> collection .getLinks ().add (
8280 new Link ()
83- .href (LinksConfigProps .LINK_PREFIX + request .path () + separator + value )
81+ .href (appendLinkPath ( LinksConfigProps .LINK_PREFIX + request .path (), value ) )
8482 .type (MediaType .APPLICATION_JSON_VALUE )
8583 .rel ("child" )));
8684
@@ -91,7 +89,7 @@ public void generatePropertyValueLinks(ServerRequest request, CollectionMetadata
9189 .type (MediaType .APPLICATION_JSON_VALUE )
9290 .rel ("self" ));
9391 collection .getLinks ().add (new Link ()
94- .href (self + separator + "items" )
92+ .href (appendLinkPath ( self , "items" ) )
9593 .type (StaccatoMediaType .APPLICATION_GEO_JSON_VALUE )
9694 .rel ("items" ));
9795 collection .getLinks ().add (new Link ()
@@ -128,9 +126,44 @@ public String getSelfString(ServerRequest request) {
128126 */
129127 public Link buildItemLink (String collectionId , String itemId ) {
130128 return new Link ()
131- .href (LinksConfigProps .LINK_PREFIX + "/ collections/" + collectionId + "/ items/" + itemId )
129+ .href (appendLinkPath ( LinksConfigProps .LINK_PREFIX , " collections" , collectionId , " items" , itemId ) )
132130 .type (StaccatoMediaType .APPLICATION_GEO_JSON_VALUE )
133131 .rel ("item" );
134132 }
135133
134+ /**
135+ * Appends path to url while preserving url context
136+ *
137+ * @param url The original url
138+ * @param subPaths The sub paths to be appended at the end of the url,
139+ * sub paths should not contain leading or trailing slashes
140+ * @return The url with appended sub path. If arguments are malformed, the original url is returned.
141+ */
142+ public static String appendLinkPath (String url , String ...subPaths ) {
143+ String result = url ;
144+ try {
145+ URL originalLink = new URL (url );
146+ String newPath = originalLink .getPath ();
147+
148+ for (String subPath : subPaths ) {
149+ String separator = newPath .endsWith ("/" ) ? "" : "/" ;
150+ newPath += separator + subPath ;
151+ }
152+ URI newLink = new URI (
153+ originalLink .getProtocol (),
154+ originalLink .getAuthority (),
155+ newPath ,
156+ originalLink .getQuery (),
157+ null
158+ );
159+ result = newLink .toString ();
160+ } catch (MalformedURLException e ) {
161+ log .warn ("LinkGenerator encounters malformed url " + e .toString ());
162+ return url ;
163+ } catch (URISyntaxException e ) {
164+ log .warn ("LinkGenerator encounteres uri syntax exception " + e .toString ());
165+ }
166+ return result ;
167+ }
168+
136169}
0 commit comments