org.apache.wink.common.internal.utils.UriHelper Maven / Gradle / Ivy
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*******************************************************************************/
package org.apache.wink.common.internal.utils;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.PathSegment;
import org.apache.wink.common.RestConstants;
import org.apache.wink.common.internal.MultivaluedMapImpl;
import org.apache.wink.common.internal.PathSegmentImpl;
import org.apache.wink.common.internal.uri.UriEncoder;
import org.apache.wink.common.internal.uri.UriPathNormalizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Various methods for URI/URL manipulation.
*/
public class UriHelper {
private static final Logger logger = LoggerFactory.getLogger(UriHelper.class);
// no instances
private UriHelper() {
}
/**
* Normalize URI:
*
* - The last character in URI is NOT '/'
*
*
* @param uri input URI
* @return normalized URI
*/
public static String removeTrailingSlash(String uri) {
if (uri != null && uri.length() > 0 && uri.lastIndexOf('/') == uri.length() - 1) {
return uri.substring(0, uri.length() - 1);
}
return uri;
}
/**
* Remove parameters for the url
*
* @param requestUri input URI
* @return input URI without query string
*/
public static String stripQueryString(String requestUri) {
int idx;
if (requestUri != null && (idx = requestUri.lastIndexOf('?')) != -1) {
requestUri = requestUri.substring(0, idx);
return removeTrailingSlash(requestUri);
}
return requestUri;
}
/**
* Get query string.
*
* @param requestUri input URI
* @return query string from input URI
*/
public static String getQueryString(String requestUri) {
int idx;
if (requestUri != null && (idx = requestUri.lastIndexOf('?')) != -1) {
return requestUri.substring(idx + 1, requestUri.length());
}
return null;
}
/**
* Strip name (last section in the path).
*
* @param requestUri input URI
* @return part of URI after the last slash
*/
public static String stripName(String requestUri) {
int idx;
if (requestUri != null) {
requestUri = removeTrailingSlash(requestUri);
if ((idx = requestUri.lastIndexOf('/')) != -1) {
return requestUri.substring(0, idx);
}
}
return null;
}
/**
* Get the last section of the path.
*
* @param uri URI.
* @return name.
*/
public static String getNameFromPath(String uri) {
if (uri != null) {
uri = removeTrailingSlash(uri);
return uri.substring(uri.lastIndexOf('/') + 1, uri.length());
}
return null;
}
/**
* Hide password from the URL.
*
* @param url the URL to hide the password from
* @return URL with user information removed
*/
public static String hidePassword(URI url) {
if (url == null) {
return null;
}
String ui = url.getRawUserInfo();
if (ui == null) {
return url.toString();
}
String str = url.toString();
int pidx = str.indexOf(ui);
if (pidx < 0) {
return str;
}
return str.substring(0, pidx) + str.substring(pidx + ui.length() + 1); // 1 for @
}
/**
* Hide password from the URL.
*
* @param url the URL to hide the password from
* @return URL with user information removed
*/
public static String hidePassword(String url) {
if (url == null) {
return null;
}
return hidePassword(URI.create(url));
}
/**
* Hides password from all the urls in the list.
*
* @param urls the list of urls to hide the password from
* @return URL with user information removed
*/
public static List hidePassword(List urls) {
if (urls == null) {
return urls;
}
List ret = new ArrayList(urls.size());
for (String url : urls) {
ret.add(hidePassword(url));
}
return ret;
}
/**
* Relativize URI path. Can add ".." and "." segments.
*
* @param basePath relative against this path
* @param pathToRelativize path to change
* @return a relativized path
*/
public static String relativize(String basePath, String pathToRelativize) {
String normalizeBasePath = removeStartSlash(UriPathNormalizer.normalize(basePath));
String[] splitBase = StringUtils.fastSplit(normalizeBasePath, "/", false); //$NON-NLS-1$
String normalizedPathToRelativize =
removeStartSlash(UriPathNormalizer.normalize(pathToRelativize));
String[] splitPath = StringUtils.fastSplit(normalizedPathToRelativize, "/", false); //$NON-NLS-1$
int pos = 0;
while (pos < splitBase.length && pos < splitPath.length
&& splitBase[pos].equals(splitPath[pos])) {
pos++;
}
StringBuilder result = new StringBuilder();
if (pos == splitBase.length && !normalizeBasePath.endsWith("/")) { // at the end of base //$NON-NLS-1$
// .../baseEnd
String lastSegment = splitBase[pos - 1];
result.append(lastSegment);
for (; pos < splitPath.length; pos++) {
if (result.length() != 0)
result.append('/');
result.append(splitPath[pos]);
}
} else if (pos == splitBase.length) { // at the end of base .../baseEnd/
for (; pos < splitPath.length; pos++) {
if (result.length() != 0)
result.append('/');
result.append(splitPath[pos]);
}
} else {
for (int posBase = pos; posBase < splitBase.length - 1; posBase++) {
if (result.length() != 0)
result.append('/');
result.append(".."); //$NON-NLS-1$
}
if (normalizeBasePath.endsWith("/")) { //$NON-NLS-1$
if (result.length() != 0)
result.append('/');
result.append(".."); //$NON-NLS-1$
}
for (; pos < splitPath.length; pos++) {
if (result.length() != 0)
result.append('/');
result.append(splitPath[pos]);
}
}
if (result.length() == 0) {
result.append('.');
}
return result.toString();
}
/**
* @param s a non-null string
* @return s value with optional first character '/' removed
*/
public static String removeStartSlash(String s) {
if (s.startsWith("/")) { //$NON-NLS-1$
return s.substring(1);
} else {
return s;
}
}
/**
* Appends a path a baseUri.
*
* @param baseUri the base uri, can but needn't to end with a '/', not
* null
* @param path path append, can but needn't to start with a '/'
* @return a string with path appended path-wise correctly to the path
*/
public static String appendPathToBaseUri(String baseUri, String path) {
if (baseUri == null)
throw new NullPointerException("baseUri"); //$NON-NLS-1$
if (path == null || path.length() == 0)
return baseUri;
boolean endSlash = baseUri.endsWith("/"); //$NON-NLS-1$
boolean startSlash = path.charAt(0) == '/';
if (startSlash && endSlash) {
return baseUri + path.substring(1);
} else if (startSlash || endSlash) {
return baseUri + path;
} else {
return baseUri + '/' + path;
}
}
/**
* Append an alt parameter to an uri.
*
* @param uri an uri without any parameters, not null
* @param mediaType the value of the alt parameter, not null
* @return string containing an uri, media type is uri-encoded
*/
public static String appendAltToPath(String uri, MediaType mediaType) {
if (uri == null)
throw new NullPointerException("uri"); //$NON-NLS-1$
if (mediaType == null)
throw new NullPointerException("mediaType"); //$NON-NLS-1$
StringBuilder result = new StringBuilder(uri);
if (uri.length() == 0)
result.append('.');
char appendCharacter = '?';
// if the uri already has query parameters
if ((uri.indexOf('?') != -1)) {
appendCharacter = '&';
}
result.append(appendCharacter);
result.append(RestConstants.REST_PARAM_MEDIA_TYPE);
result.append('=');
result.append(MediaTypeUtils.toEncodedString(mediaType));
return result.toString();
}
/**
* Constructs a string with URI in unescaped form. Use as woraround with
* unencoding/double encoding problems with URI constructor,
* new Uri(constructUri(...)).toASCIIString()
should be the
* original URI.
*
* @param scheme URI.getScheme
* @param userInfo URI.getRawUserInfo
* @param host URI.getRawHost
* @param port URI.getPort; -1 = no port
* @param path URI.getRawPath
* @param query URI.getRawQuery
* @param fragment URI.getRawFragment
* @return URI with reserved characters escaped
*/
public static String contructUri(String scheme,
String userInfo,
String host,
int port,
String path,
String query,
String fragment) {
StringBuilder buffer = new StringBuilder();
if (scheme != null) {
buffer.append(scheme);
buffer.append("://"); //$NON-NLS-1$
}
if (userInfo != null) {
buffer.append(userInfo);
buffer.append("@"); //$NON-NLS-1$
}
if (host != null) {
buffer.append(host);
}
if (port != -1) {
buffer.append(":"); //$NON-NLS-1$
buffer.append(port);
}
if (path != null) {
buffer.append(path);
}
if (query != null) {
buffer.append("?"); //$NON-NLS-1$
buffer.append(query);
}
if (fragment != null) {
buffer.append("#"); //$NON-NLS-1$
buffer.append(fragment);
}
return buffer.toString();
}
/**
* The method builds the query parameters String e.g.
* param1=value1¶m2=value2
*
* @param queryParams Map of query parameters
* @param escapeKeyParam indicates if to escape the parameter's name and
* value
* @return String the query parameters String
*/
public static String getQueryParamsStr(Map queryParams, boolean escapeKeyParam) {
if (queryParams == null || queryParams.size() < 1) {
return ""; //$NON-NLS-1$
}
StringBuilder queryParamsStr = new StringBuilder();
Set queryParamsKey = queryParams.keySet();
String[] params;
String appendStr = ""; //$NON-NLS-1$
for (String key : queryParamsKey) {
params = queryParams.get(key);
if (params == null) {
continue;
}
for (String paramInArray : params) {
queryParamsStr.append(appendStr);
queryParamsStr.append(escapeKeyParam ? UriEncoder.encodeString(key) : key)
.append("=").append(escapeKeyParam ? UriEncoder.encodeString(paramInArray) //$NON-NLS-1$
: paramInArray);
appendStr = "&"; //$NON-NLS-1$
}
}
return queryParamsStr.toString();
}
/**
* The method appends query parameters to path
*
* @param uri
* @param queryParams Map of query parameters
* @param escapeKeyParam indicates if to escape the parameter's name and
* value
* @return String the path with query parameters
*/
public static String appendQueryParamsToPath(String uri,
Map queryParams,
boolean escapeKeyParam) {
if (uri == null)
throw new NullPointerException("uri"); //$NON-NLS-1$
if (queryParams == null || queryParams.size() < 1) {
return uri;
}
StringBuilder result = new StringBuilder(uri);
if (uri.length() == 0) {
result.append('.');
}
char appendCharacter = '?';
// if the uri already has query parameters
if ((uri.indexOf('?') != -1)) {
appendCharacter = '&';
}
return uri + appendCharacter + getQueryParamsStr(queryParams, escapeKeyParam);
}
/**
* Parses a uri path into a list of PathSegements
*
* @param path the path to parse
* @return list of PathSegement instances
*/
public static List parsePath(String path) {
logger.trace("parsePath({}) entry", path); //$NON-NLS-1$
String[] segmentsArray = StringUtils.fastSplitTemplate(path, "/", true); //$NON-NLS-1$
List pathSegments = new ArrayList(segmentsArray.length);
// go over all the segments and add them
for (String segment : segmentsArray) {
pathSegments.add(new PathSegmentImpl(segment));
}
logger.trace("parsePath() exit returning {}", pathSegments); //$NON-NLS-1$
return pathSegments;
}
/**
* Parses a query string (without the leading '?') into a map of parameters
* and values
*
* @param queryStr the query strin to parse
* @return a map of query parameters and values
*/
public static MultivaluedMap parseQuery(String queryStr) {
MultivaluedMap query = new MultivaluedMapImpl();
if (queryStr == null || queryStr.length() == 0) {
return query;
}
String[] paramsArray = StringUtils.fastSplit(queryStr, "&"); //$NON-NLS-1$
for (String param : paramsArray) {
int index = param.indexOf('=');
String name = param;
String value = null;
if (index != -1) {
name = param.substring(0, index);
value = param.substring(index + 1);
}
query.add(name, value);
}
return query;
}
/**
* Normalize input uri according to
* href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986 section 6.2.2. -
* Syntax-Based Normalization
*
* @param string
* @return normalized instance of uri
*/
public static String normalize(String uri) {
// Path Segment Normalization
uri = UriPathNormalizer.normalize(uri);
// Percent-Encoding Normalization & Case Normalization
uri = UriEncoder.normalize(uri);
return uri;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy