geoportal-data-viewer-app/src/main/java/org/gcube/portlets/user/geoportaldataviewer/server/gis/WMSUrlValidator.java

336 lines
11 KiB
Java
Raw Normal View History

2020-10-27 16:04:34 +01:00
package org.gcube.portlets.user.geoportaldataviewer.server.gis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.spatial.data.geoutility.GeoWmsServiceUtility;
import org.gcube.spatial.data.geoutility.bean.WmsParameters;
import org.gcube.spatial.data.geoutility.util.HttpRequestUtil;
import org.gcube.spatial.data.geoutility.wms.WmsUrlValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class GisViewerWMSUrlValidator.
*
2023-06-01 16:26:34 +02:00
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Jan 28, 2016
2020-10-27 16:04:34 +01:00
*/
public class WMSUrlValidator {
public static final String GEOSERVER = "/geoserver";
private static final String WMS = "wms";
private static final String OWS = "ows";
private HashMap<String, String> parametersValue = new HashMap<String, String>();
private String wmsRequestURI;
private String wmsServiceEndPoint;
2020-10-27 16:04:34 +01:00
private String layerName;
private String wmsNoStandardParameters = "";
private Map<String, String> mapWmsNoStandardParams;
private WmsUrlValidator urlValidator;
private static final Logger LOG = LoggerFactory.getLogger(WMSUrlValidator.class);
/**
2020-11-19 15:19:27 +01:00
* Instantiates a new WMS url validator.
2020-10-27 16:04:34 +01:00
*
2023-06-01 16:26:34 +02:00
* @param wmsRequest the wms request
2020-11-19 15:19:27 +01:00
* @param inputLayerName the input layer name
2020-10-27 16:04:34 +01:00
* @throws Exception the exception
*/
2023-06-01 16:26:34 +02:00
public WMSUrlValidator(String wmsRequest, String inputLayerName) throws Exception {
LOG.debug("WMSURLValidator wmsRequest: " + wmsRequest);
LOG.debug("WMSURLValidator layerName: " + inputLayerName);
2020-10-27 16:04:34 +01:00
2023-06-01 16:26:34 +02:00
if (wmsRequest == null || wmsRequest.isEmpty())
2020-10-27 16:04:34 +01:00
throw new Exception("WMS request is null or empty");
this.wmsRequestURI = wmsRequest.trim();
2023-06-01 16:26:34 +02:00
// VALIDATION WMS
int endpointLastCharIndex = wmsRequest.lastIndexOf("?");
// No '?' char found
if (endpointLastCharIndex == -1) {
LOG.info("Char '?' not found, setting last index the end of the URI");
endpointLastCharIndex = wmsRequest.length();
}
String readWMSServiceEndpoint = wmsRequest.substring(0, endpointLastCharIndex);
this.wmsServiceEndPoint = readWMSServiceEndpoint;
2020-10-27 16:04:34 +01:00
try {
2023-06-01 16:26:34 +02:00
// VALIDATE WMS SERVICE FOR WEB MAP SERVER
if (!HttpRequestUtil.urlExists(this.wmsServiceEndPoint, true)) {
LOG.warn("baseWmsServiceUrl: " + wmsServiceEndPoint + " is not valid URL!!");
this.wmsServiceEndPoint = readWMSServiceEndpoint;
2020-10-27 16:04:34 +01:00
}
} catch (Exception e) {
LOG.error("Error on validating the endpoint: " + this.wmsServiceEndPoint, e);
boolean isOwsService = GeoWmsServiceUtility.isOWSSerice(this.wmsRequestURI);
LOG.info("Retrying by appending suffix WMS or WFS...");
this.wmsServiceEndPoint = appendWmsServiceToBaseUrl(readWMSServiceEndpoint, isOwsService);
2020-10-27 16:04:34 +01:00
}
2023-06-01 16:26:34 +02:00
// VALIDATION FOR THREDDS - FIND LAYER NAME INTO WMS PATH
if (this.layerName == null || this.layerName.isEmpty()) {
2020-10-27 16:04:34 +01:00
this.layerName = WmsUrlValidator.getValueOfParameter(WmsParameters.LAYERS, wmsRequest);
2023-06-01 16:26:34 +02:00
if (this.layerName == null || this.layerName.isEmpty())
2020-10-27 16:04:34 +01:00
throw new Exception("Layer name is null or empty");
}
LOG.info("WMSURLValidator found endpoint: " + wmsServiceEndPoint);
2020-10-27 16:04:34 +01:00
parametersValue.put(WmsParameters.LAYERS.getParameter(), this.layerName);
}
/**
* Append wms service to base url.
*
2023-06-01 16:26:34 +02:00
* @param url the url
2020-10-27 16:04:34 +01:00
* @param isOwsServer the is ows server
* @return the string
*/
2023-06-01 16:26:34 +02:00
public String appendWmsServiceToBaseUrl(String url, boolean isOwsServer) {
2020-10-27 16:04:34 +01:00
2023-06-01 16:26:34 +02:00
if (url.contains("/" + WMS) || url.contains("/" + OWS))
2020-10-27 16:04:34 +01:00
return url;
2023-06-01 16:26:34 +02:00
if (url.lastIndexOf("/") != url.length()) {
url += "/";
2020-10-27 16:04:34 +01:00
}
2023-06-01 16:26:34 +02:00
if (isOwsServer)
return url += OWS;
2020-10-27 16:04:34 +01:00
else
2023-06-01 16:26:34 +02:00
return url += WMS;
2020-10-27 16:04:34 +01:00
}
/**
2023-06-01 16:26:34 +02:00
* Method: getFullWmsUrlRequest Create a correct wms url request Returns:
2020-10-27 16:04:34 +01:00
* {String}.
*
2023-06-01 16:26:34 +02:00
* @param returnEmptyParameter if true the wms url returned contains also
* wms parameter with empty value, none
* otherwise. and mandatory wms parameters
* that does not found are filled with empty
* values
2020-10-27 16:04:34 +01:00
* @param fillEmptyParameterAsDefault the fill empty parameter as default
* @return a correct wms url request in formatted string like this:
2023-06-01 16:26:34 +02:00
* "wmsserver?key1=value1&key2=value2&key3=value3"
2020-10-27 16:04:34 +01:00
*/
2023-06-01 16:26:34 +02:00
public String parseWMSRequest(boolean returnEmptyParameter, boolean fillEmptyParameterAsDefault) {
2020-10-27 16:04:34 +01:00
urlValidator = new org.gcube.spatial.data.geoutility.wms.WmsUrlValidator(wmsRequestURI);
String fullWmsUrlBuilded;
try {
fullWmsUrlBuilded = urlValidator.parseWmsRequest(returnEmptyParameter, fillEmptyParameterAsDefault);
parametersValue.putAll(urlValidator.getMapWmsParameters());
String ln = parametersValue.get(WmsParameters.LAYERS.name());
2023-06-01 16:26:34 +02:00
LOG.debug("Comparing layer name from Wms request: " + ln + ", with OnLineResource layerName: "
+ this.layerName);
if (ln == null || ln.isEmpty() || ln.compareTo(this.layerName) != 0) {
LOG.info(
"Layer name into wms request is different to OnLineResource layers name, replacing layer name: "
+ this.layerName);
2020-10-27 16:04:34 +01:00
parametersValue.put(WmsParameters.LAYERS.getParameter(), this.layerName);
2023-06-01 16:26:34 +02:00
urlValidator.getMapWmsParameters().put(
org.gcube.spatial.data.geoutility.bean.WmsParameters.LAYERS.getParameter(), this.layerName);
fullWmsUrlBuilded = org.gcube.spatial.data.geoutility.wms.WmsUrlValidator.setValueOfParameter(
org.gcube.spatial.data.geoutility.bean.WmsParameters.LAYERS, fullWmsUrlBuilded, this.layerName,
true);
2020-10-27 16:04:34 +01:00
}
// logger.trace("parametersValue: "+parametersValue);
mapWmsNoStandardParams = new HashMap<String, String>(urlValidator.getMapWmsNoStandardParams().size());
mapWmsNoStandardParams.putAll(urlValidator.getMapWmsNoStandardParams());
wmsNoStandardParameters = urlValidator.getWmsNoStandardParameters();
2023-06-01 16:26:34 +02:00
} catch (Exception e) {
LOG.error("An error occurred during wms uri build, returning uri: " + wmsRequestURI, e);
2020-10-27 16:04:34 +01:00
fullWmsUrlBuilded = wmsRequestURI;
}
2023-06-01 16:26:34 +02:00
LOG.trace("GisViewerWMSUrlValidator parseWMSRequest returning full wms url: " + fullWmsUrlBuilded);
2020-10-27 16:04:34 +01:00
return fullWmsUrlBuilded;
}
/**
* Gets the web map server host.
*
* @param wmsRequest the wms request
2023-06-01 16:26:34 +02:00
* @return the web map server host, (geoserver URI or the wmsRequest substring
* from start to index of '?' char (if exists))
2020-10-27 16:04:34 +01:00
*/
2023-06-01 16:26:34 +02:00
public WebMapServerHost getWebMapServerHost(String wmsRequest) {
2020-10-27 16:04:34 +01:00
WebMapServerHost webMapServerHost = new WebMapServerHost();
2023-06-01 16:26:34 +02:00
if (wmsRequest == null)
return webMapServerHost; // uri is empty
2020-10-27 16:04:34 +01:00
int end = wmsRequest.toLowerCase().lastIndexOf("?");
2023-06-01 16:26:34 +02:00
if (end == -1) {
LOG.trace("char ? not found in geoserver uri, return: " + wmsRequest);
return webMapServerHost; // uri is empty
2020-10-27 16:04:34 +01:00
}
String webMapServerBaseURL = wmsRequest.substring(0, wmsRequest.toLowerCase().lastIndexOf("?"));
int index = webMapServerBaseURL.lastIndexOf(GEOSERVER);
2023-06-01 16:26:34 +02:00
if (index > -1) { // FOUND the string GEOSERVER into URL
LOG.trace("found geoserver string: " + GEOSERVER + " in " + webMapServerBaseURL);
2020-10-27 16:04:34 +01:00
2023-06-01 16:26:34 +02:00
// THERE IS SCOPE?
2020-10-27 16:04:34 +01:00
int lastSlash = webMapServerBaseURL.lastIndexOf("/");
2023-06-01 16:26:34 +02:00
int includeGeoserverString = index + GEOSERVER.length();
int endUrl = lastSlash > includeGeoserverString ? lastSlash : includeGeoserverString;
LOG.trace("indexs - lastSlash: [" + lastSlash + "], includeGeoserverString: [" + includeGeoserverString
+ "], endUrl: [" + endUrl + "]");
int startScope = includeGeoserverString + 1 < endUrl ? includeGeoserverString + 1 : endUrl; // INCLUDE SLASH
2020-10-27 16:04:34 +01:00
String scope = webMapServerBaseURL.substring(startScope, endUrl);
2023-06-01 16:26:34 +02:00
LOG.trace("geoserver url include scope: " + webMapServerBaseURL.substring(includeGeoserverString, endUrl));
2020-10-27 16:04:34 +01:00
webMapServerHost.setHost(webMapServerBaseURL.substring(0, endUrl));
webMapServerHost.setScope(scope);
return webMapServerHost;
2023-06-01 16:26:34 +02:00
} else {
LOG.trace("the string 'geoserver' not found in " + webMapServerBaseURL);
2020-10-27 16:04:34 +01:00
// GET LAST INDEX OF '/' AND CONCATENATE GEOSERVER
2023-06-01 16:26:34 +02:00
String urlConn = webMapServerBaseURL.substring(0, webMapServerBaseURL.lastIndexOf("/")) + GEOSERVER;
LOG.trace("tentative concatenating string 'geoserver' at http url " + urlConn);
2020-10-27 16:04:34 +01:00
try {
2023-06-01 16:26:34 +02:00
if (HttpRequestUtil.urlExists(urlConn, false)) {
LOG.trace("url: " + urlConn + " - open a connection, return " + urlConn);
2020-10-27 16:04:34 +01:00
webMapServerHost.setHost(urlConn);
return webMapServerHost;
2023-06-01 16:26:34 +02:00
} else
LOG.trace("url: " + urlConn + " - not open a connection");
2020-10-27 16:04:34 +01:00
} catch (Exception e) {
2023-06-01 16:26:34 +02:00
LOG.error("url connection is wrong at :" + urlConn);
2020-10-27 16:04:34 +01:00
}
String uriWithoutParameters = wmsRequest.substring(0, end);
2023-06-01 16:26:34 +02:00
LOG.trace("url connection, returned: " + uriWithoutParameters);
2020-10-27 16:04:34 +01:00
webMapServerHost.setHost(uriWithoutParameters);
return webMapServerHost;
}
}
/**
* Gets the wms service end point.
2020-10-27 16:04:34 +01:00
*
* @return the wms service end point
2020-10-27 16:04:34 +01:00
*/
public String getWmsServiceEndPoint() {
2020-10-27 16:04:34 +01:00
return wmsServiceEndPoint;
2020-10-27 16:04:34 +01:00
}
/**
* Gets the url validator.
*
* @return the urlValidator
*/
public org.gcube.spatial.data.geoutility.wms.WmsUrlValidator getUrlValidator() {
return urlValidator;
}
/**
* Gets the wms no standard parameters.
*
* @return the wms no standard parameters
*/
public String getWmsNoStandardParameters() {
return wmsNoStandardParameters;
}
/**
* Gets the value of parsed wms parameter.
*
* @param parameter the parameter
* @return the value of parsed wms parameter parsed from wms request.
*/
2023-06-01 16:26:34 +02:00
public String getValueOfParsedWMSParameter(WmsParameters parameter) {
2020-10-27 16:04:34 +01:00
return parametersValue.get(parameter.getParameter());
}
/**
* Gets the value of parameter.
*
2023-06-01 16:26:34 +02:00
* @param wmsParam the wms param
2020-10-27 16:04:34 +01:00
* @param wmsUrlParameters the wms url parameters
* @return the value of parameter
*/
2023-06-01 16:26:34 +02:00
public static String getValueOfParameter(WmsParameters wmsParam, String wmsUrlParameters) {
2020-10-27 16:04:34 +01:00
return WmsUrlValidator.getValueOfParameter(wmsParam, wmsUrlParameters);
}
/**
* Sets the value of parameter.
*
2023-06-01 16:26:34 +02:00
* @param wmsParam the wms param
2020-10-27 16:04:34 +01:00
* @param wmsUrlParameters the wms url parameters
2023-06-01 16:26:34 +02:00
* @param newValue the new value
* @param addIfNotExists the add if not exists
2020-10-27 16:04:34 +01:00
* @return the string
*/
2023-06-01 16:26:34 +02:00
public static String setValueOfParameter(WmsParameters wmsParam, String wmsUrlParameters, String newValue,
boolean addIfNotExists) {
2020-10-27 16:04:34 +01:00
return WmsUrlValidator.setValueOfParameter(wmsParam, wmsUrlParameters, newValue, addIfNotExists);
}
/**
* Gets the layer name.
*
* @return the layer name
*/
public String getLayerName() {
return layerName;
}
/**
* Gets the styles as list.
*
* @return the styles as list
*/
public List<String> getStylesAsList() {
List<String> listStyles = new ArrayList<String>();
String styles = getValueOfParsedWMSParameter(WmsParameters.STYLES);
2023-06-01 16:26:34 +02:00
if (styles != null && !styles.isEmpty()) {
2020-10-27 16:04:34 +01:00
String[] arrayStyle = styles.split(",");
for (String style : arrayStyle) {
2023-06-01 16:26:34 +02:00
if (style != null && !style.isEmpty())
2020-10-27 16:04:34 +01:00
listStyles.add(style);
}
}
return listStyles;
}
/**
* Gets the map wms no standard params.
*
* @return the map wms no standard params
*/
public Map<String, String> getMapWmsNoStandardParams() {
return mapWmsNoStandardParams;
}
}