com.sap.cloud.sdk.s4hana.connectivity.ServiceUriBuilder Maven / Gradle / Ivy
/*
* Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved.
*/
package com.sap.cloud.sdk.s4hana.connectivity;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
import javax.annotation.Nonnull;
import com.google.common.collect.Sets;
/**
* Used to build S/4HANA service URI, considering parameters such as base URI and relative path.
*/
public class ServiceUriBuilder
{
protected static final String ERP_ENDPOINT_CLOUD = "/sap/bc/rest/sap/fi_map/";
protected static final String ERP_ENDPOINT_ON_PREMISE = "/sap/hcpint/map/bm/";
private static final Set testSystemPaths = Sets.newHashSet();
/**
* Adds a test system path. For internal use only.
*
* @param uri
* Adds the path contained in the URI to the collection of endpoints to be removed.
*/
public static synchronized void registerTestSystem( final URI uri )
{
testSystemPaths.add(encloseSlashesIfMissing(uri.getPath()));
}
/**
* Adds a slash ('/') as a prefix if it is not yet present.
*
* @param path
* The String to prefix with a slash.
* @return A String guaranteed to start with a slash.
*/
protected static String prependSlashIfMissing( final String path )
{
return path.startsWith("/") ? path : "/" + path;
}
/**
* Adds a slash ('/') as a suffix if it is not yet present.
*
* @param path
* The String to suffix with a slash.
* @return A String guaranteed to end with a slash.
*/
protected static String appendSlashIfMissing( final String path )
{
return path.endsWith("/") ? path : path + "/";
}
/**
* Encloses the given String with a slash ('/') if they are not yet present.
*
* @param path
* The String to pre- and suffix with a slash.
* @return A String guaranteed to start and end with a slash.
*/
protected static String encloseSlashesIfMissing( final String path )
{
return prependSlashIfMissing(appendSlashIfMissing(path));
}
/**
* Removes all known and registered endpoints from the path of the given URI.
*
* See {@link #registerTestSystem(URI)}, {@link #ERP_ENDPOINT_CLOUD}, and {@link #ERP_ENDPOINT_ON_PREMISE}.
*
* @param baseUri
* The URI to take the path to be adjusted from.
* @return The path without any of the registered and known endpoints.
*/
protected String removeErpEndpointPaths( final URI baseUri )
{
String path = encloseSlashesIfMissing(baseUri.getPath());
path = path.replaceAll(ERP_ENDPOINT_CLOUD, "");
path = path.replaceAll(ERP_ENDPOINT_ON_PREMISE, "");
for( final String testSystemPath : testSystemPaths ) {
path = path.replaceAll(testSystemPath, "");
}
return encloseSlashesIfMissing(path);
}
/**
* Builds a ERP service URI for a given relative path.
*
* Therefore the path contained in {@code baseUri} is stripped of all known and registered endpoints (see
* {@link #registerTestSystem(URI)}) and gets the {@code relativePath} added.
*
* @param baseUri
* The URI to replace/adjust the path property.
* @param relativePath
* The relative path to be used.
*
* @return A new URI object based on the given {@code baseUri}, modified by adjusting the contained path with the
* given {@code relativePath}.
* @throws IllegalArgumentException
* If the new URI object could not be created, most likely due to a wrongly formatted relativePath.
*/
public URI build( @Nonnull final URI baseUri, @Nonnull final String relativePath )
{
try {
final String path = removeErpEndpointPaths(baseUri) + relativePath.replaceFirst("^/", "");
return new URI(
baseUri.getScheme(),
baseUri.getUserInfo(),
baseUri.getHost(),
baseUri.getPort(),
path,
baseUri.getQuery(),
baseUri.getFragment());
}
catch( final URISyntaxException e ) {
throw new IllegalArgumentException("Failed to build ERP service URI.", e);
}
}
}