/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.rest.support;
import com.eviware.soapui.impl.rest.RestURIParser;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
/**
* Basic RestURIParser using java's .net.URI and .net.URL class
*
* @author Shadid Chowdhury
* @since 4.5.6
*/
public class RestURIParserImpl implements RestURIParser {
private static final String SCHEME_SEPARATOR = "://";
private static final String DEFAULT_SCHEME = "http";
private String resourcePath = "";
private String query = "";
private String scheme = "";
private String authority = "";
public RestURIParserImpl(String uriString) throws MalformedURLException {
preValidation(uriString);
parseURI(uriString);
postValidation();
}
private void preValidation(String uriString) throws MalformedURLException {
if (uriString == null || uriString.isEmpty()) {
throw new MalformedURLException("Empty URI");
}
}
private void parseURI(String uriString) throws MalformedURLException {
try {
if (isAPossibleEndPointWithoutScheme(uriString)) {
uriString = DEFAULT_SCHEME + SCHEME_SEPARATOR + uriString;
}
parseWithURI(uriString);
} catch (URISyntaxException e) {
parseWithURL(uriString);
}
}
private void postValidation() throws MalformedURLException {
if (!validateScheme()) {
throw new MalformedURLException("URI contains unsupported protocol. Supported protocols are HTTP/HTTPS");
} else if (!validateAuthority()) {
throw new MalformedURLException("Invalid endpoint");
}
}
private boolean validateScheme() throws MalformedURLException {
String scheme = getScheme();
return scheme.isEmpty() || scheme.matches("(HTTP|http).*");
}
private boolean validateAuthority() throws MalformedURLException {
String endpoint = getEndpoint();
return endpoint.isEmpty() || !endpoint.matches(".*[\\\\]+.*");
}
@Override
public String getEndpoint() {
String endpoint;
if (authority.isEmpty()) {
endpoint = "";
} else if (scheme.isEmpty()) {
endpoint = DEFAULT_SCHEME + SCHEME_SEPARATOR + authority;
} else {
endpoint = scheme + SCHEME_SEPARATOR + authority;
}
return endpoint;
}
@Override
public String getResourceName() {
String path = getResourcePath();
if (path.isEmpty()) {
return path;
}
String[] splitResourcePath = path.split("/");
if (splitResourcePath.length == 0) {
return "";
}
String resourceName = splitResourcePath[splitResourcePath.length - 1];
if (resourceName.startsWith(";")) {
return "";
}
resourceName = resourceName.replaceAll("\\{", "").replaceAll("\\}", "");
if (resourceName.contains(";")) {
resourceName = resourceName.substring(0, resourceName.indexOf(";"));
}
return resourceName.substring(0, 1).toUpperCase() + resourceName.substring(1);
}
@Override
public String getScheme() {
return scheme;
}
@Override
public String getResourcePath() {
String path = resourcePath;
path = addPrefixSlash(path);
return path;
}
@Override
public String getQuery() {
return query;
}
private String addPrefixSlash(String path) {
if (!path.startsWith("/") && !path.isEmpty()) {
path = "/" + path;
}
return path;
}
private void parseWithURI(String uriString) throws URISyntaxException {
URI uri = new URI(uriString);
resourcePath = (uri.getPath() == null ? "" : uri.getPath());
query = (uri.getQuery() == null ? "" : uri.getQuery());
scheme = (uri.getScheme() == null ? "" : uri.getScheme());
authority = (uri.getAuthority() == null ? "" : uri.getAuthority());
}
private boolean isURIWithoutScheme(String uriString) {
return !uriString.matches("[a-zA-Z]+\\:[\\/\\/]+.*");
}
private boolean isAPossibleEndPointWithoutScheme(String uriString) {
int indexOfDot = uriString.indexOf(".");
return indexOfDot > 0 && isURIWithoutScheme(uriString);
}
private void parseWithURL(String uriString) throws MalformedURLException {
URL url;
try {
url = new URL(uriString);
resourcePath = (url.getPath() == null ? "" : url.getPath());
query = (url.getQuery() == null ? "" : url.getQuery());
scheme = (url.getProtocol() == null ? "" : url.getProtocol());
authority = (url.getAuthority() == null ? "" : url.getAuthority());
} catch (MalformedURLException e) {
parseManually(uriString);
}
}
private void parseManually(String uriString) {
resourcePath = uriString;
query = "";
scheme = "";
authority = "";
int startIndexOfQuery = uriString.indexOf('?');
if (startIndexOfQuery >= 0) {
query = uriString.substring(startIndexOfQuery + 1);
resourcePath = uriString.substring(0, startIndexOfQuery);
}
int startIndexOfResource = resourcePath.indexOf('/');
if (startIndexOfResource >= 0) {
resourcePath = resourcePath.substring(startIndexOfResource + 1);
authority = resourcePath.substring(0, startIndexOfResource);
}
}
}