org.eclipse.basyx.vab.modelprovider.VABPathTools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of basyx.sdk Show documentation
Show all versions of basyx.sdk Show documentation
BaSyx v1.0.0 July 6, 2021.
The newest version!
/*******************************************************************************
* Copyright (C) 2021 the Eclipse BaSyx Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipse.basyx.vab.modelprovider;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.basyx.submodel.metamodel.map.submodelelement.operation.Operation;
import org.eclipse.basyx.vab.exception.provider.MalformedRequestException;
/**
* Utility functions to handle a VAB path
*
* @author kuhn, espen
*
*/
public class VABPathTools {
public static final String SEPERATOR = "/";
/**
* Removes leading and trailing slashes
*
* @param path
* @return
*/
public static String stripSlashes(String path) {
while (path.startsWith("/")) {
path = path.substring(1);
}
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
return path;
}
/**
* Encodes sensitive characters, e.g. "/" and "#"
*
* @param elem
* @return
*/
public static String encodePathElement(String elem) {
try {
return URLEncoder.encode(elem, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* Decodes sensitive characters, e.g. "/" and "#"
*
* @param elem
* @return
*/
public static String decodePathElement(String encodedElem) {
try {
return URLDecoder.decode(encodedElem, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
/**
* Skips the first N entries of a path. E.g. for a/b/c skipping 2 means
* returning c
*
* @param path
* @param toSkip
* @return
*/
public static String skipEntries(String path, int toSkip) {
StringBuilder builder = new StringBuilder();
String[] splitted = VABPathTools.splitPath(path);
for (int i = toSkip; i < splitted.length; i++) {
builder.append(splitted[i]);
// Don't add slash at last step
if (i < splitted.length - 1) {
builder.append("/");
}
}
return builder.toString();
}
/**
* Returns the Nth entry of a path, e.g. the second entry of a/b/c is
* c
*
* @param path
* @param entry
* @return
*/
public static String getEntry(String path, int entry) {
return VABPathTools.splitPath(path)[entry];
}
/**
* Split a path into path elements, e.g. /a/b/c -> [ a, b, c ]
*/
public static String[] splitPath(String path) {
// Return null result for null argument
if (path == null) {
return null;
}
// includes null-values, "" and "/";
if (VABPathTools.isEmptyPath(path)) {
return new String[] {};
}
// Remove leading separator, otherwise /a leads to {"", "a"}
String fixedPath = removePrefix(path, SEPERATOR);
String[] splitted = fixedPath.split(SEPERATOR);
List nonEmptySplitted = new ArrayList<>();
// Remove empty entries
for (String s : splitted) {
if (!s.isEmpty()) {
nonEmptySplitted.add(s);
}
}
return nonEmptySplitted.toArray(new String[nonEmptySplitted.size()]);
}
/**
* Remove the last element from the path
*/
public static String getParentPath(String path) {
// Return null result for null argument
if (path == null) {
return null;
}
if (isEmptyPath(path)) {
return "";
}
int lastIndex = path.lastIndexOf(SEPERATOR);
if (lastIndex == path.length() - 1) {
lastIndex = path.lastIndexOf(SEPERATOR, path.length() - 2);
}
if (lastIndex >= 0) {
return removePrefix(path.substring(0, lastIndex), SEPERATOR);
} else {
return "";
}
}
/**
* Get the last element of a path. Return "" if there is no element in the path
*/
public static String getLastElement(String path) {
// Return null result for null argument
if (path == null) {
return null;
}
String[] elements = splitPath(path);
if (elements.length > 0) {
return elements[elements.length - 1];
} else {
return "";
}
}
/**
* Remove prefix from beginning of path
*/
public static String removePrefix(String path, String prefix) {
// Return null result for null argument
if (path == null) {
return null;
}
if (VABPathTools.isEmptyPath(path)) {
// same result as for any other "empty" path, like "" and "/"
return "";
}
if (path.startsWith(prefix)) {
return path.substring(prefix.length());
} else {
return path;
}
}
public static String append(String path, String element) {
// Return null result for null argument
if (path == null || element == null) {
return null;
}
if (path.lastIndexOf(SEPERATOR) == path.length() - 1) {
return path + element;
} else {
return path + SEPERATOR + element;
}
}
/**
* Build and return a path with pathElements[startIndex] as the root element
*/
public static String buildPath(String[] pathElements, int startIndex) {
// Return null result for null argument
if (pathElements == null) {
return null;
}
if (startIndex >= pathElements.length) {
return "";
}
// This will store the resulting path
StringBuilder result = new StringBuilder();
// Build path
for (int i = startIndex; i < pathElements.length; i++)
result.append(pathElements[i] + SEPERATOR);
// Remove last '/'
result.deleteCharAt(result.length() - 1);
// Return created path
return result.toString();
}
/**
* Check if the path to an VAB elements leads to the invocation of an operation. In this case, the
* element path conforms to /aas/submodels/{subModelId}/submodelElements/{operationId}/invoke
*/
public static boolean isOperationInvokationPath(String path) {
// null-Paths are no operation paths
if (path == null) {
return false;
}
// Split path
String[] pathElements = splitPath(path);
if(pathElements.length == 0) {
return false;
}
// Check if last path element is "invoke" or "operations" is contained anywhere
return pathElements[pathElements.length - 1].startsWith(Operation.INVOKE) || isOperationPath(path);
}
private static boolean isOperationPath(String path) {
String lowerCasePath = path.toLowerCase();
return lowerCasePath.startsWith("operations/") || path.toLowerCase().contains("/operations/");
}
/**
* Check, if the path does not contain any elements.
*/
public static boolean isEmptyPath(String path) {
return path.equals("") || path.equals("/");
}
/**
* Gets the first endpoint of a path.
* @path
* A path that can contain 0..* endpoints.
* @return
* The first address entry of a path. The address entry is the first endpoint combined with a protocol.
* If there is no protocol defined, the address entry is empty ("").
* E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return basyx://127.0.0.1:6998,
* https://localhost/test//basyx://127.0.0.1:6998/ will return https://localhost/test
* and http://localhost/test/ will return "".
*/
public static String getFirstEndpoint(String fullPath) {
// Return null result for null argument
if (fullPath == null) {
return null;
}
if (isEmptyPath(fullPath) || !fullPath.contains("//")) {
return "";
} else {
String[] splitted = fullPath.split("//");
return splitted[0] + "//" + splitted[1];
}
}
/**
* Removes the first endpoint from a path. See {@link #getAddressEntry}
* @path
* @return
* The first endpoint. E.g. basyx://127.0.0.1:6998//https://localhost/test/ will return
* https://localhost/test/.
*
*/
public static String removeFirstEndpoint(String fullPath) {
// Return null result for null argument
if (fullPath == null) {
return null;
}
if (isEmptyPath(fullPath)) {
return "";
} else if (!fullPath.contains("//")) {
return fullPath;
} else {
String firstEndpoint = fullPath.replaceFirst(getFirstEndpoint(fullPath), "");
if (firstEndpoint.startsWith("//")) {
firstEndpoint = firstEndpoint.replaceFirst("//", "");
}
return firstEndpoint;
}
}
/**
* Concatenate two paths
*/
public static String concatenatePaths(String... paths) {
// Return null result for null argument
if (paths == null || paths.length == 0) {
return null;
}
// Store result
StringBuffer result = new StringBuffer();
// Flag that indicates whether processed path segment is first segment
boolean isFirst = true;
// Process all path segments
for (String pathSegment : paths) {
// Return empty result, if any element is null
if (pathSegment == null) {
return null;
}
// Remove leading and trailing "/" from pathsegment
while (pathSegment.endsWith("/"))
pathSegment = pathSegment.substring(0, pathSegment.length() - 1);
while (pathSegment.startsWith("/"))
pathSegment = pathSegment.substring(1);
// Add path to result; if its first segment, do not split with "'"
if (!isFirst)
result.append("/");
else
isFirst = false;
result.append(pathSegment);
}
// Return combined path
return result.toString();
}
/**
* Checks if path is null, if yes throw exception
*
* @param path
*/
public static void checkPathForNull(String path) throws MalformedRequestException {
if (path == null) {
throw new MalformedRequestException("Path is not allowed to be null");
}
}
/**
* Strips the last path element if it is "invoke"
*
* @param path
* @return path without last element "invoke" or unchanged path
*/
public static String stripInvokeFromPath(String path) {
if(path == null)
return null;
if(getLastElement(path).startsWith(Operation.INVOKE)) {
return getParentPath(path);
}
return path;
}
/**
* Gets the path from a URL
* e.g "http://localhost:8080/path/to/test.file" results in "/path/to/test.file"
*
* @param url
* @return the path from the URL
*/
public static String getPathFromURL(String url) {
if(url == null) {
return null;
}
if(url.contains("://")) {
// Find the ":" and and remove the "http://" from the url
int index = url.indexOf(":") + 3;
url = url.substring(index);
// Find the first "/" from the URL (now without the "http://") and remove everything before that
index = url.indexOf("/");
url = url.substring(index);
// Recursive call to deal with more than one server parts
// (e.g. basyx://127.0.0.1:6998//https://localhost/test/)
return getPathFromURL(url);
} else {
// Make sure the path has a / at the start
if(!url.startsWith("/")) {
url = "/" + url;
}
return url;
}
}
/**
* Harmonizes a path so that it will always and with the suffix and no ending
* slash (even if the suffix contains one).
*
* @param path
* to harmonize
* @param suffix
* to check for existance and append if necessary
* @return harmonized path
*/
public static String harmonizePathWithSuffix(String path, String suffix) {
String strippedPath = stripSlashes(path);
String strippedSuffix = stripSlashes(suffix);
if (strippedPath.endsWith("/" + strippedSuffix)) {
return strippedPath;
} else {
return VABPathTools.concatenatePaths(strippedPath, strippedSuffix);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy