package org.gcube.portlets.user.geoportaldataviewer.server; import static org.gcube.application.geoportal.client.GeoportalAbstractPlugin.statefulMongoConcessioni; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.gcube.application.geoportal.client.legacy.ConcessioniManagerI; import org.gcube.application.geoportal.common.model.legacy.Concessione; import org.gcube.application.geoportal.common.model.legacy.LayerConcessione; import org.gcube.application.geoportal.common.model.legacy.UploadedImage; import org.gcube.application.geoportalcommon.ConvertToDataViewModel; import org.gcube.application.geoportalcommon.GeoNaDataViewerProfileReader; import org.gcube.application.geoportalcommon.GeoportalCommon; import org.gcube.application.geoportalcommon.shared.GeoNaDataViewerProfile; import org.gcube.application.geoportalcommon.shared.GeoNaItemRef; import org.gcube.application.geoportalcommon.shared.LayerItem; import org.gcube.application.geoportalcommon.shared.gis.BoundsMap; import org.gcube.application.geoportalcommon.shared.products.ConcessioneDV; import org.gcube.application.geoportalcommon.shared.products.model.LayerConcessioneDV; import org.gcube.application.geoportalcommon.shared.products.model.UploadedImageDV; import org.gcube.application.geoportalcommon.util.URLParserUtil; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerService; import org.gcube.portlets.user.geoportaldataviewer.server.gis.FeatureParser; import org.gcube.portlets.user.geoportaldataviewer.server.gis.WMSUrlValidator; import org.gcube.portlets.user.geoportaldataviewer.server.util.SessionUtil; import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaSpatialQueryResult; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerObject; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wfs.FeatureRow; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.GeoInformationForWMSRequest; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.Styles; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.wms.ZAxis; import org.gcube.spatial.data.geoutility.GeoNcWMSMetadataUtility; import org.gcube.spatial.data.geoutility.bean.LayerStyles; import org.gcube.spatial.data.geoutility.bean.LayerZAxis; import org.gcube.spatial.data.geoutility.bean.WmsParameters; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; /** * The server side implementation of the RPC service. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * Nov 12, 2020 */ @SuppressWarnings("serial") public class GeoportalDataViewerServiceImpl extends RemoteServiceServlet implements GeoportalDataViewerService { public static final String PRODUCT_ID = "product_id"; /** The Constant LOG. */ private static final Logger LOG = LoggerFactory.getLogger(GeoportalDataViewerServiceImpl.class); /** * Parses the wms request. * * @param wmsRequest the wms request * @param layerName the layer name * @return the geo information for WMS request * @throws Exception the exception */ @Override public GeoInformationForWMSRequest parseWmsRequest(String wmsRequest, String layerName) throws Exception { return loadGeoInfoForWmsRequest(wmsRequest, layerName); } /** * Load geo info for wms request. * * @param wmsLink the wms link * @param layerName the layer name * @return the geo information for WMS request * @throws Exception the exception */ public static GeoInformationForWMSRequest loadGeoInfoForWmsRequest(String wmsLink, String layerName) throws Exception { try { WMSUrlValidator validator = new WMSUrlValidator(wmsLink, layerName); String wmsServiceHost = validator.getWmsServiceHost(); String validWMSRequest = validator.parseWMSRequest(true, true); layerName = validator.getLayerName(); String versionWms = validator.getValueOfParsedWMSParameter(WmsParameters.VERSION); String crs = validator.getValueOfParsedWMSParameter(WmsParameters.CRS); // HashMap mapWmsNotStandard = new HashMap(); if (validator.getMapWmsNoStandardParams() != null) { mapWmsNotStandard.putAll(validator.getMapWmsNoStandardParams()); } // GeoNcWMSMetadataUtility geoGS = new GeoNcWMSMetadataUtility(validWMSRequest, 4000); // STYLES LayerStyles layerStyle = geoGS.loadStyles(); Map mapNcWmsStyles = layerStyle.getMapNcWmsStyles() == null ? new HashMap(1) : layerStyle.getMapNcWmsStyles(); mapWmsNotStandard.putAll(mapNcWmsStyles); // MAP STYLES INTO GWT-SERIALIZABLE OBJECT Styles styles = new Styles(layerStyle.getGeoStyles(), layerStyle.getMapNcWmsStyles(), layerStyle.isNcWms()); // ZAxis LayerZAxis layerZAxis = geoGS.loadZAxis(); // MAP ZAXIS INTO GWT-SERIALIZABLE OBJECT ZAxis zAxis = layerZAxis != null ? new ZAxis(layerZAxis.getUnits(), layerZAxis.isPositive(), layerZAxis.getValues()) : null; return new GeoInformationForWMSRequest(wmsServiceHost, validWMSRequest, layerName, versionWms, crs, mapWmsNotStandard, styles, styles.isNcWms(), zAxis); } catch (Exception e) { String msg = "An error occurred during wms request validation for layer: " + layerName; LOG.error(msg, e); throw new Exception(msg); } } /** * Gets the data result. * * @param layerObjects the layer objects * @param mapSrsName the map srs name * @param selectBBOX the select BBOX * @param maxWFSFeature the max WFS feature * @param zoomLevel the zoom level * @return the data result */ @Override public List getDataResult(List layerObjects, String mapSrsName, BoundsMap selectBBOX, int maxWFSFeature, double zoomLevel) { LOG.info("getDataResult called"); List listDAO = new ArrayList(layerObjects.size()); for (LayerObject layerObject : layerObjects) { GeoNaSpatialQueryResult geoDAO = new GeoNaSpatialQueryResult(); List features = FeatureParser.getWFSFeatures(layerObject.getLayerItem(), mapSrsName, selectBBOX, maxWFSFeature); LOG.debug("For layer name: " + layerObject.getLayerItem().getName() + " got features: " + features); geoDAO.setFeatures(features); for (FeatureRow fRow : features) { if (fRow.getMapProperties() != null) { List concessioneIds = fRow.getMapProperties().get("product_id"); if (concessioneIds != null && concessioneIds.size() > 0) { String cId = concessioneIds.get(0); try { List listUI = getUploadedImagesForId("Concessione", cId, 1); Map> mapImages = new LinkedHashMap>(); mapImages.put(cId, listUI); geoDAO.setMapImages(mapImages); } catch (Exception e) { LOG.warn("Error on loading uploaded images for concessione: " + cId, e); } } } } geoDAO.setSourceLayerObject(layerObject); LOG.info("For layer name: " + layerObject.getLayerItem().getName() + " got " + features.size() + " feature/s"); listDAO.add(geoDAO); } LOG.info("returning " + listDAO + " geona data objects"); return listDAO; } /** * Gets the uploaded images for id. * * @param itemType the item type * @param itemId the item id. It is the mongoId * @param maxImages the max images * @return the uploaded images for id * @throws Exception the exception */ @Override public List getUploadedImagesForId(String itemType, String itemId, int maxImages) throws Exception { LOG.info("getUploadedImagesForId [itemId: " + itemId + ", itemType: " + itemType + "] called"); if (itemType == null) throw new Exception("Invalid parameter. The itemType is null"); if (itemId == null) throw new Exception("Invalid parameter. The itemId is null"); List listUI = null; try { SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); if (itemType.equalsIgnoreCase("concessione")) { LOG.info("Trying to get concessione for id " + itemId); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); SessionUtil.getCurrentToken(this.getThreadLocalRequest(), true); ConcessioniManagerI concessioniManager = statefulMongoConcessioni().build(); Concessione concessione = concessioniManager.getById(itemId); if (concessione != null) { LOG.info("For id " + itemId + ", got concessione " + concessione.getNome() + " from service"); List images = concessione.getImmaginiRappresentative(); if (images != null) { listUI = new ArrayList(); int max = maxImages < images.size() ? maxImages : images.size(); for (int i = 0; i < max; i++) { UploadedImageDV ui = ConvertToDataViewModel.toUploadedImage(images.get(i)); listUI.add(ui); } LOG.info("For id " + itemId + ", got " + listUI.size() + " image/s"); } } else throw new Exception("Concessione with id '" + itemId + "' not available"); } return listUI; } catch (Exception e) { String erroMsg = UploadedImage.class.getSimpleName() + " not available for " + Concessione.class.getSimpleName() + " with id " + itemId; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * Gets the layers for id. * * @param itemType the item type * @param itemId the item id * @return the layers for id * @throws Exception the exception */ @Override public List getLayersForId(String itemType, String itemId) throws Exception { LOG.info("getLayersForId [itemId: " + itemId + ", itemType: " + itemType + "] called"); if (itemType == null) throw new Exception("Invalid parameter. The itemType is null"); if (itemId == null) throw new Exception("Invalid parameter. The itemId is null"); List listLayers = null; try { SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); if (itemType.equalsIgnoreCase("concessione")) { LOG.info("Trying to get concessione for id " + itemId); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); SessionUtil.getCurrentToken(this.getThreadLocalRequest(), true); ConcessioniManagerI concessioniManager = statefulMongoConcessioni().build(); Concessione concessione = concessioniManager.getById(itemId); if (concessione != null) { LOG.info("For id " + itemId + ", got concessione " + concessione.getNome() + " from service"); listLayers = new ArrayList(); if (concessione.getPianteFineScavo() != null) { for (LayerConcessione lc : concessione.getPianteFineScavo()) { listLayers.add(ConvertToDataViewModel.toLayerConcessione(lc)); } } if (concessione.getPosizionamentoScavo() != null) { LayerConcessioneDV thePosizScavo = ConvertToDataViewModel .toLayerConcessione(concessione.getPosizionamentoScavo()); if (thePosizScavo != null) listLayers.add(thePosizScavo); } } else throw new Exception("Concessione with id '" + itemId + "' not available"); } LOG.info("For id " + itemId + ", returning " + listLayers.size() + " layer/s"); return listLayers; } catch (Exception e) { String erroMsg = "Layers are not available for " + Concessione.class.getSimpleName() + " with id " + itemId; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * Gets the concessione for id. * * @param mongoId the mongo id * @return the concessione for id * @throws Exception the exception */ @Override public ConcessioneDV getConcessioneForId(String mongoId) throws Exception { LOG.info("getConcessioneForId " + mongoId + " called"); ConcessioneDV concessionDV = null; if (mongoId == null) throw new Exception("Invalid parameter. The itemId is null"); try { LOG.info("Trying to get record for id " + mongoId); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); SessionUtil.getCurrentToken(this.getThreadLocalRequest(), true); // Obtain the client ConcessioniManagerI manager = statefulMongoConcessioni().build(); Concessione concessione = manager.getById(mongoId); LOG.info("Got concessione for mongoId " + mongoId); if (concessione != null) { concessionDV = ConvertToDataViewModel.toConcessione(concessione); } if (concessionDV == null) throw new Exception("Concessione with id '" + mongoId + "' not available"); LOG.debug("For id " + mongoId + " returning " + ConcessioneDV.class.getSimpleName() + ": " + concessionDV); return concessionDV; } catch (Exception e) { String erroMsg = Concessione.class.getSimpleName() + " with id '" + mongoId + "' not available"; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * Gets the parameters from URL. * * @param theURL the the URL * @param parameters the parameters * @return a map with couple (paramKey, paramValue) */ public Map getParametersFromURL(String theURL, List parameters) { if (theURL == null) return null; if (parameters == null || parameters.size() == 0) return null; Map hashParameters = new HashMap(parameters.size()); for (String paramKey : parameters) { String paramValue = URLParserUtil.extractValueOfParameterFromURL(paramKey, theURL); hashParameters.put(paramKey, paramValue); } return hashParameters; } /** * Gets the my login. * * @return the my login */ @Override public String getMyLogin() { try { GCubeUser user = SessionUtil.getCurrentUser(this.getThreadLocalRequest()); if (user == null) return null; return user.getUsername(); } catch (Exception e) { LOG.warn("Error on getting the login, am I out of portal? Returning null"); return null; } } /** * Gets the layer for type. * * @param layerType the layer type * @return the layer for type * @throws Exception the exception */ @Override public GeoInformationForWMSRequest getLayerForType(String layerType) throws Exception { LOG.info("Called getLayerForType for:" + layerType); if (layerType == null || layerType.isEmpty()) throw new Exception("The input parameter layerType is null or empty"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GeoNaDataViewerProfileReader gdvp = new GeoNaDataViewerProfileReader("geoportal-data-viewer-app"); GeoNaDataViewerProfile profile = gdvp.readProfileFromInfrastrucure(); LOG.info("Read profile: " + profile); String lowerLayerType = layerType.toLowerCase(); LOG.info("Reading map layers for type:" + lowerLayerType); LayerItem layer = profile.getMapLayers().get(lowerLayerType); if (layer == null || layer.getWmsLink() == null) throw new Exception( "The layer type " + lowerLayerType + " has not been found. Please check your input parameter"); if (layer.getWmsLink() == null) throw new Exception("The layer type " + lowerLayerType + " has not a WMS Link associated. Please check your input parameter"); return parseWmsRequest(layer.getWmsLink(), null); } /** * Gets the geo na data view profile. * * @return the geo na data view profile * @throws Exception the exception */ @Override public GeoNaDataViewerProfile getGeoNaDataViewProfile() throws Exception { LOG.info("getGeoNaDataViewProfile called"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GeoportalCommon gc = new GeoportalCommon(); org.gcube.application.geoportalcommon.shared.GeoNaDataViewerProfile profile = gc.getGeoNaDataViewProfile(null); LOG.info("Returning profile: " + profile); return profile; } /** * Gets the public links for. * * @param item the item * @return the public links for * @throws Exception the exception */ @Override public GeoNaItemRef getPublicLinksFor(GeoNaItemRef item) throws Exception { LOG.info("getPublicLinksFor called for: " + item); try { if (item == null) throw new Exception("Bad request, the item is null"); if (item.getItemId() == null) throw new Exception("Bad request, the item id is null"); if (item.getItemType() == null) throw new Exception("Bad request, the item type is null"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GeoportalCommon gc = new GeoportalCommon(); return gc.getPublicLinksFor(item); } catch (Exception e) { LOG.error("Error on getPublicLinksFor for: " + item, e); throw new Exception("Share link not available for this item. Try later or contact the support. Error: " + e.getMessage()); } } /** * Checks if is session expired. * * @return true, if is session expired * @throws Exception the exception */ public boolean isSessionExpired() throws Exception { return SessionUtil.isSessionExpired(this.getThreadLocalRequest()); } }