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

336 lines
11 KiB
Java

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.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Jan 28, 2016
*/
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;
private String layerName;
private String wmsNoStandardParameters = "";
private Map<String, String> mapWmsNoStandardParams;
private WmsUrlValidator urlValidator;
private static final Logger LOG = LoggerFactory.getLogger(WMSUrlValidator.class);
/**
* Instantiates a new WMS url validator.
*
* @param wmsRequest the wms request
* @param inputLayerName the input layer name
* @throws Exception the exception
*/
public WMSUrlValidator(String wmsRequest, String inputLayerName) throws Exception {
LOG.debug("WMSURLValidator wmsRequest: " + wmsRequest);
LOG.debug("WMSURLValidator layerName: " + inputLayerName);
if (wmsRequest == null || wmsRequest.isEmpty())
throw new Exception("WMS request is null or empty");
this.wmsRequestURI = wmsRequest.trim();
// 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;
try {
// VALIDATE WMS SERVICE FOR WEB MAP SERVER
if (!HttpRequestUtil.urlExists(this.wmsServiceEndPoint, true)) {
LOG.warn("baseWmsServiceUrl: " + wmsServiceEndPoint + " is not valid URL!!");
this.wmsServiceEndPoint = readWMSServiceEndpoint;
}
} 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);
}
// VALIDATION FOR THREDDS - FIND LAYER NAME INTO WMS PATH
if (this.layerName == null || this.layerName.isEmpty()) {
this.layerName = WmsUrlValidator.getValueOfParameter(WmsParameters.LAYERS, wmsRequest);
if (this.layerName == null || this.layerName.isEmpty())
throw new Exception("Layer name is null or empty");
}
LOG.info("WMSURLValidator found endpoint: " + wmsServiceEndPoint);
parametersValue.put(WmsParameters.LAYERS.getParameter(), this.layerName);
}
/**
* Append wms service to base url.
*
* @param url the url
* @param isOwsServer the is ows server
* @return the string
*/
public String appendWmsServiceToBaseUrl(String url, boolean isOwsServer) {
if (url.contains("/" + WMS) || url.contains("/" + OWS))
return url;
if (url.lastIndexOf("/") != url.length()) {
url += "/";
}
if (isOwsServer)
return url += OWS;
else
return url += WMS;
}
/**
* Method: getFullWmsUrlRequest Create a correct wms url request Returns:
* {String}.
*
* @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
* @param fillEmptyParameterAsDefault the fill empty parameter as default
* @return a correct wms url request in formatted string like this:
* "wmsserver?key1=value1&key2=value2&key3=value3"
*/
public String parseWMSRequest(boolean returnEmptyParameter, boolean fillEmptyParameterAsDefault) {
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());
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);
parametersValue.put(WmsParameters.LAYERS.getParameter(), this.layerName);
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);
}
// logger.trace("parametersValue: "+parametersValue);
mapWmsNoStandardParams = new HashMap<String, String>(urlValidator.getMapWmsNoStandardParams().size());
mapWmsNoStandardParams.putAll(urlValidator.getMapWmsNoStandardParams());
wmsNoStandardParameters = urlValidator.getWmsNoStandardParameters();
} catch (Exception e) {
LOG.error("An error occurred during wms uri build, returning uri: " + wmsRequestURI, e);
fullWmsUrlBuilded = wmsRequestURI;
}
LOG.trace("GisViewerWMSUrlValidator parseWMSRequest returning full wms url: " + fullWmsUrlBuilded);
return fullWmsUrlBuilded;
}
/**
* Gets the web map server host.
*
* @param wmsRequest the wms request
* @return the web map server host, (geoserver URI or the wmsRequest substring
* from start to index of '?' char (if exists))
*/
public WebMapServerHost getWebMapServerHost(String wmsRequest) {
WebMapServerHost webMapServerHost = new WebMapServerHost();
if (wmsRequest == null)
return webMapServerHost; // uri is empty
int end = wmsRequest.toLowerCase().lastIndexOf("?");
if (end == -1) {
LOG.trace("char ? not found in geoserver uri, return: " + wmsRequest);
return webMapServerHost; // uri is empty
}
String webMapServerBaseURL = wmsRequest.substring(0, wmsRequest.toLowerCase().lastIndexOf("?"));
int index = webMapServerBaseURL.lastIndexOf(GEOSERVER);
if (index > -1) { // FOUND the string GEOSERVER into URL
LOG.trace("found geoserver string: " + GEOSERVER + " in " + webMapServerBaseURL);
// THERE IS SCOPE?
int lastSlash = webMapServerBaseURL.lastIndexOf("/");
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
String scope = webMapServerBaseURL.substring(startScope, endUrl);
LOG.trace("geoserver url include scope: " + webMapServerBaseURL.substring(includeGeoserverString, endUrl));
webMapServerHost.setHost(webMapServerBaseURL.substring(0, endUrl));
webMapServerHost.setScope(scope);
return webMapServerHost;
} else {
LOG.trace("the string 'geoserver' not found in " + webMapServerBaseURL);
// GET LAST INDEX OF '/' AND CONCATENATE GEOSERVER
String urlConn = webMapServerBaseURL.substring(0, webMapServerBaseURL.lastIndexOf("/")) + GEOSERVER;
LOG.trace("tentative concatenating string 'geoserver' at http url " + urlConn);
try {
if (HttpRequestUtil.urlExists(urlConn, false)) {
LOG.trace("url: " + urlConn + " - open a connection, return " + urlConn);
webMapServerHost.setHost(urlConn);
return webMapServerHost;
} else
LOG.trace("url: " + urlConn + " - not open a connection");
} catch (Exception e) {
LOG.error("url connection is wrong at :" + urlConn);
}
String uriWithoutParameters = wmsRequest.substring(0, end);
LOG.trace("url connection, returned: " + uriWithoutParameters);
webMapServerHost.setHost(uriWithoutParameters);
return webMapServerHost;
}
}
/**
* Gets the wms service end point.
*
* @return the wms service end point
*/
public String getWmsServiceEndPoint() {
return wmsServiceEndPoint;
}
/**
* 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.
*/
public String getValueOfParsedWMSParameter(WmsParameters parameter) {
return parametersValue.get(parameter.getParameter());
}
/**
* Gets the value of parameter.
*
* @param wmsParam the wms param
* @param wmsUrlParameters the wms url parameters
* @return the value of parameter
*/
public static String getValueOfParameter(WmsParameters wmsParam, String wmsUrlParameters) {
return WmsUrlValidator.getValueOfParameter(wmsParam, wmsUrlParameters);
}
/**
* Sets the value of parameter.
*
* @param wmsParam the wms param
* @param wmsUrlParameters the wms url parameters
* @param newValue the new value
* @param addIfNotExists the add if not exists
* @return the string
*/
public static String setValueOfParameter(WmsParameters wmsParam, String wmsUrlParameters, String newValue,
boolean addIfNotExists) {
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);
if (styles != null && !styles.isEmpty()) {
String[] arrayStyle = styles.split(",");
for (String style : arrayStyle) {
if (style != null && !style.isEmpty())
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;
}
}