
com.sap.cloud.sdk.cloudplatform.connectivity.UriPathMerger Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of connectivity Show documentation
Show all versions of connectivity Show documentation
Cloud platform abstraction for general-purpose connectivity.
The newest version!
/*
* Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.cloudplatform.connectivity;
import java.net.URI;
import java.net.URISyntaxException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
import com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationPathsNotMergeableException;
import com.sap.cloud.sdk.cloudplatform.exception.ShouldNotHappenException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;
/**
* Utility class offering the ability to merge two URIs.
*/
public class UriPathMerger
{
private static final Logger logger = CloudLoggerFactory.getLogger(UriPathMerger.class);
/**
* Merges two {@code URI} paths, checking that both {@code URIs} have the same scheme, host and port.
*
* @param destinationUri
* The {@code URI} pointing to the destination.
* @param requestUri
* The {@code URI} identifying the request.
*
* @throws DestinationPathsNotMergeableException
* If either of the request paths of the the given URIs are {@code null} or the URIs differ in the used
* schema, host, or port.
*
* @return The merged {@code URI}, representing the given request executed on the given destination.
*/
@Nonnull
public URI merge( @Nonnull final URI destinationUri, @Nullable final URI requestUri )
throws DestinationPathsNotMergeableException
{
try {
if( requestUri != null ) {
String requestRawPath = requestUri.getRawPath();
if( logger.isDebugEnabled() ) {
logger.debug("Merging request path: " + requestRawPath);
}
final String destinationUriRawPath = destinationUri.getRawPath();
assertRequestUriMatchesDestinationUri(destinationUri, requestUri);
if( logger.isDebugEnabled() ) {
logger.debug("Successfully merged request path: " + requestRawPath);
}
// If the request path is relative we need to merge it with the destination path.
// If, instead, the request path is absolute, then the request path already contains the full path
// and doesn't need to be merged with the destination path.
if( !requestUri.isAbsolute() ) {
requestRawPath = mergeUriRawPaths(destinationUriRawPath, requestRawPath);
}
final URI mergedUri = destinationUri.resolve(requestRawPath);
return new URIBuilder(mergedUri)
.setUserInfo(requestUri.getUserInfo())
.setCustomQuery(requestUri.getQuery())
.setFragment(requestUri.getFragment())
.build();
} else {
String requestRawPath = destinationUri.getRawPath();
requestRawPath = requestRawPath.replaceAll("^/", "");
requestRawPath = "/" + requestRawPath;
return new URIBuilder(destinationUri).setPath(requestRawPath).build();
}
}
catch( final URISyntaxException e ) {
throw new ShouldNotHappenException("Failed to merge request URI.", e);
}
}
private
void
assertRequestUriMatchesDestinationUri( @Nonnull final URI destinationUri, @Nonnull final URI requestUri )
throws DestinationPathsNotMergeableException
{
if( requestUri.getHost() != null ) {
final boolean isSchemeEqual = destinationUri.getScheme().equalsIgnoreCase(requestUri.getScheme());
final boolean isHostEqual = destinationUri.getHost().equalsIgnoreCase(requestUri.getHost());
final boolean isPortEqual = destinationUri.getPort() == requestUri.getPort();
if( !(isSchemeEqual && isHostEqual && isPortEqual) ) {
throw new DestinationPathsNotMergeableException(
"URIs defined in destination '"
+ destinationUri
+ "' and supplied by application code '"
+ requestUri
+ "' differ.");
}
}
}
/**
* Merges two {@link URI} paths into one, preventing path duplications.
*
* @throws DestinationPathsNotMergeableException
* If either of the given paths is {@code null}.
*
* @return The merged path as String.
*/
@Nonnull
private String mergeUriRawPaths( @Nullable final String firstRawPath, @Nullable final String secondRawPath )
throws DestinationPathsNotMergeableException
{
if( firstRawPath == null || secondRawPath == null ) {
throw new DestinationPathsNotMergeableException("Cannot merge URI paths that are null.");
}
final String first = firstRawPath.trim().replaceFirst("^/", "");
final String second = secondRawPath.trim().replaceFirst("^/", "");
final String result;
if( second.isEmpty() ) {
result = first;
} else {
if( second.startsWith(first) ) {
result = second;
} else {
result = (first.endsWith("/") ? first : first + "/") + second;
}
}
return result.startsWith("/") ? result : "/" + result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy