package org.gcube.portlets.user.geoportaldataviewer.server; import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.projects; import static org.gcube.application.geoportal.client.plugins.GeoportalAbstractPlugin.useCaseDescriptors; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.bson.Document; import org.gcube.application.geoportal.common.model.configuration.Configuration; import org.gcube.application.geoportal.common.model.configuration.Index; import org.gcube.application.geoportal.common.model.document.Project; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.rest.Projects; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.GeoportalCommon; import org.gcube.application.geoportalcommon.ProjectDVBuilder; import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller; import org.gcube.application.geoportalcommon.geoportal.UseCaseDescriptorCaller; import org.gcube.application.geoportalcommon.shared.GNADataViewerConfigProfile; import org.gcube.application.geoportalcommon.shared.GeoportalItemReferences; import org.gcube.application.geoportalcommon.shared.LayerItem; import org.gcube.application.geoportalcommon.shared.ResultSetPaginatedData; import org.gcube.application.geoportalcommon.shared.SearchingFilter; import org.gcube.application.geoportalcommon.shared.geoportal.ConfigurationDV; import org.gcube.application.geoportalcommon.shared.geoportal.DocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.ResultDocumentDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.GCubeSDIViewerLayerDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.IndexLayerDV; import org.gcube.application.geoportalcommon.shared.geoportal.materialization.innerobject.PayloadDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_DATA_HANDLER; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.HandlerDeclarationDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.UseCaseDescriptorDV; import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; import org.gcube.application.geoportalcommon.shared.gis.BoundsMap; import org.gcube.application.geoportalcommon.shared.products.ConcessioneDV; 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.mongoservice.GeoportalServiceIdentityProxy; import org.gcube.portlets.user.geoportaldataviewer.server.util.ContextRequest; import org.gcube.portlets.user.geoportaldataviewer.server.util.SessionUtil; import org.gcube.portlets.user.geoportaldataviewer.shared.GCubeCollection; import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaSpatialQueryResult; import org.gcube.portlets.user.geoportaldataviewer.shared.ItemFieldsResponse; import org.gcube.portlets.user.geoportaldataviewer.shared.ViewerConfiguration; import org.gcube.portlets.user.geoportaldataviewer.shared.faults.ControlledError; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.BaseMapLayer; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerObject; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerObjectType; 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.portlets.user.urlshortener.UrlShortener; 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"; private static final Logger LOG = LoggerFactory.getLogger(GeoportalDataViewerServiceImpl.class); private static final String CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE = "MAP_IMAGE_PREVIEW_FOR_CONCESSIONE"; /** * The Enum COMMON_IMAGES_FORMAT. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Oct 18, 2022 */ public static enum COMMON_IMAGES_FORMAT { gif, png, jpeg, jpg, bmp, tif, tiff, svg, avif, webp } /** * The Class ImageDetector. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Oct 18, 2022 */ public static class ImageDetector { /** * Gets the names. * * @param e the e * @return the names */ private static String[] getNames(Class> e) { return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new); } public static List listFormatImages; static { String[] arrayImgs = ImageDetector.getNames(COMMON_IMAGES_FORMAT.class); listFormatImages = Arrays.asList(arrayImgs); } /** * Checks if is image. * * @param mimeType the mime type * @return true, if is image */ public static boolean isImage(String mimeType) { if (mimeType == null || mimeType.isEmpty()) return false; String inputImageFormat = mimeType.replaceAll("image/", ""); return listFormatImages.contains(inputImageFormat); } } /** * Gets the GNA data viewe config profile. * * @return the GNA data viewe config profile * @throws Exception the exception */ private GNADataViewerConfigProfile getGNADataVieweConfigProfile() throws Exception { GNADataViewerConfigProfile profile = SessionUtil.getGNADataViewerConfigProfile(getThreadLocalRequest()); if (profile == null) { LOG.info(GNADataViewerConfigProfile.class.getSimpleName() + " is null, loading configurations from IS"); // to be sure SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GeoportalCommon geoportalComm = new GeoportalCommon(); profile = geoportalComm.readGNADataViewerConfig(null); } else { LOG.info(GNADataViewerConfigProfile.class.getSimpleName() + " read from session"); } return profile; } /** * 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 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 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, Integer maxImages) throws Exception { LOG.info("getUploadedImagesForId [itemId: " + itemId + ", itemType: " + itemType + "] called"); return getUploadedImagesForId(this.getThreadLocalRequest(), itemType, itemId, maxImages); } /** * 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"); throw new Exception("getConcessioneForId must be removed!"); /* * 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); * * GeoportalServiceIdentityProxy cms = new * GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); Concessione * concessione = cms.getItemById(mongoId); * * LOG.info("Got concessione for mongoId: " + mongoId); if (concessione != null) * { concessionDV = ConvertToDataViewModel.toConcessione(concessione); * * String userName = null; try { userName = * SessionUtil.getCurrentUser(this.getThreadLocalRequest()).getUsername(); * * } catch (Exception e) { * LOG.info("User not found in session, so going to apply the acess policies"); * } * * // TODO THIS IS A WORKAROUND WAITING FOR ADOPTING OF USER ROLES. AT THE * MOMENT, // A USER AUTHENTICATED CAN ACCESS EVERYTHING // I CAN CHECK THE * ACCCESS POLICIES IF AND ONLY IF THE USER IS NOT LOGGED IN. if (userName == * null) { * * // CHECKING ACCESS POLICY * LOG.info("Applying access policies for concessione " + mongoId + * " returned by service"); LayerConcessioneDV layerPosizionamento = * concessionDV.getPosizionamentoScavo(); if (layerPosizionamento != null) { if * (!GeoNACheckAccessPolicy.isAccessible(layerPosizionamento.getPolicy(), * userName)) { concessionDV.setPosizionamentoScavo(null); * LOG.info("Posizionamento di Scavo is not accessible by current user: " + * userName); } } * * List listLayersDV = concessionDV.getPianteFineScavo(); if * (listLayersDV != null) { List accessibleListLayersDV = * new ArrayList(); for (LayerConcessioneDV layerDV : * listLayersDV) { if (GeoNACheckAccessPolicy.isAccessible(layerDV.getPolicy(), * userName)) { accessibleListLayersDV.add(layerDV); } else { * LOG.info("(Pianta) Layer " + layerDV.getLayerName() + * " is not accessible by current user: " + userName); } } * concessionDV.setPianteFineScavo(accessibleListLayersDV); } * * AbstractRelazioneScavoDV abstractRS = * concessionDV.getAbstractRelazioneScavo(); if (abstractRS != null) { if * (!GeoNACheckAccessPolicy.isAccessible(abstractRS.getPolicy(), userName)) { * concessionDV.setAbstractRelazioneScavo(null); * LOG.info("Abstract relazione is not accessible by current user: " + * userName); } } * * RelazioneScavoDV relazioneScavo = concessionDV.getRelazioneScavo(); if * (relazioneScavo != null) { if * (!GeoNACheckAccessPolicy.isAccessible(relazioneScavo.getPolicy(), userName)) * { concessionDV.setRelazioneScavo(null); * LOG.info("Relazione scavo is not accessible by current user: " + userName); } * } * * List immagini = concessionDV.getImmaginiRappresentative(); * if (immagini != null && immagini.size() > 0) { List * accessibleListImages = new ArrayList(); * * // SHOWING ACESSIBLE IMAGES for (UploadedImageDV uploadedImageDV : immagini) * { * * if (GeoNACheckAccessPolicy.isAccessible(uploadedImageDV.getPolicy(), * userName)) { accessibleListImages.add(uploadedImageDV); } else { * LOG.info("Immagine " + uploadedImageDV.getTitolo() + * " is not accessible by current user: " + userName); } * * } concessionDV.setImmaginiRappresentative(accessibleListImages); * * } * * // END CHECKING ACCESS POLICY LOG.info("Access policies applied"); } } * * 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); GNADataViewerConfigProfile profile = getGNADataVieweConfigProfile(); 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 GNADataViewerConfigProfile getGeoNaDataViewProfile() throws Exception { LOG.info("getGeoNaDataViewProfile called"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GNADataViewerConfigProfile profile = getGNADataVieweConfigProfile(); 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 GeoportalItemReferences getPublicLinksFor(GeoportalItemReferences item) throws Exception { LOG.info("getPublicLinksFor called for: " + item); try { if (item == null) throw new Exception("Bad request, the item is null"); if (item.getProjectID() == null) throw new Exception("Bad request, the projectID is null"); if (item.getProfileID() == null) throw new Exception("Bad request, the profileID is null"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GeoportalCommon gc = new GeoportalCommon(); return gc.getPublicLinksFor(item, true); } 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()); } /** * Gets the WFS features. * * @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 WFS features */ @Override public List getWFSFeatures(List layerObjects, String mapSrsName, BoundsMap selectBBOX, int maxWFSFeature, double zoomLevel) { LOG.info("getWFSFeatures 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); 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 preview image for concessione from http session. It is the first * image retrieved from mongoService for mongoConcessioneId. Caching it into * session * * @param httpServletRequest the http servlet request * @param itemType the item type * @param mongoConcessioneId the mongo concessione id * @return the preview image for concessione */ private UploadedImageDV sessionloadPreviewImageForConcessione(HttpServletRequest httpServletRequest, String itemType, String mongoConcessioneId) { LOG.info("sessionloadPreviewImageForConcessione [mongoConcessioneId: " + mongoConcessioneId + ", itemType: " + itemType + "] called"); HttpSession session = httpServletRequest.getSession(); Map> mapImages = null; List lUI = null; try { mapImages = (LinkedHashMap) session.getAttribute(CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE); if (mapImages == null) { mapImages = new LinkedHashMap>(); } List imagePreviewForConcessione = mapImages.get(mongoConcessioneId); if (imagePreviewForConcessione == null || imagePreviewForConcessione.size() == 0) { LOG.info("Into " + CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE + " object session the mongoConcessioneId " + mongoConcessioneId + " is empty or null, loading from service and filling it"); lUI = getUploadedImagesForId(httpServletRequest, itemType, mongoConcessioneId, 1); mapImages.put(mongoConcessioneId, lUI); } lUI = mapImages.get(mongoConcessioneId); LOG.info("From " + CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE + " object session read image: " + lUI); session.setAttribute(CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE, mapImages); } catch (Exception e) { LOG.warn("Error occurred when instancing the " + UrlShortener.class.getSimpleName(), e); } if (lUI == null || lUI.isEmpty()) return null; return lUI.get(0); } /** * Gets the uploaded images for id. * * @param httpServletRequest the http servlet request * @param itemType the item type * @param itemId the item id * @param maxImages the max images * @return the uploaded images for id * @throws Exception the exception */ private List getUploadedImagesForId(HttpServletRequest httpServletRequest, String itemType, String itemId, Integer maxImages) throws Exception { LOG.info("getUploadedImagesForId [itemId: " + itemId + ", itemType: " + itemType + "] called"); throw new Exception("getUploadedImagesForId must be revisited"); /* * 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 { * * if (itemType.equalsIgnoreCase("concessione")) { * * LOG.info("Trying to get concessione for id " + itemId); * GeoportalServiceIdentityProxy cms = new * GeoportalServiceIdentityProxy(httpServletRequest); Concessione concessione = * cms.getItemById(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 list base layers. * * @return the list base layers */ @Override public List getListBaseLayers() { LOG.info("getListBaseLayers called"); List listBL = new ArrayList(); // Setting scope in the cuurent thread SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); listBL = SessionUtil.getGNABaseMaps(this.getThreadLocalRequest()); LOG.info("getListBaseLayers returning " + listBL.size() + " base maps"); return listBL; } /** * NEW CODE HERE. * * @return the initial configuration * @throws Exception the exception */ @Override public ViewerConfiguration getInitialConfiguration() throws Exception { LOG.debug("getInitialConfiguration called"); return new ContextRequest(this.getThreadLocalRequest()) { @Override protected ViewerConfiguration run() throws Exception, ControlledError { try { // ************* LOAD BASE LAYERS final ViewerConfiguration config = new ViewerConfiguration(); LOG.info("Getting initial configuration "); LOG.debug("Loading base layers.."); List listBL = SessionUtil.getGNABaseMaps(request); LOG.debug("getListBaseLayers returning " + listBL.size() + " base maps"); config.setBaseLayers(listBL); // ************** LOAD AVAILABLE COLLECTIONS LOG.debug("Loading available collections.. "); config.setAvailableCollections(new HashMap()); // TODO filter by // configured ? // gis indexed QueryRequest request = new QueryRequest(); // TODO Constant String Id = "org.gcube.portlets.user.geoportaldataviewer"; request.setFilter(Document.parse("{\"" + UseCaseDescriptor.HANDLERS + "." + org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration.ID + "\" : " + "{\"$eq\" : \"" + Id + "\"}}")); useCaseDescriptors().build().query(new QueryRequest()).forEachRemaining(u -> { try { LOG.debug("Checking configuration for collection " + u.getId()); Projects p = projects(u.getId()).build(); UseCaseDescriptorDV ucd = ConvertToDataValueObjectModel.toUseCaseDescriptorDV(u, null); Configuration ucdConfig = p.getConfiguration(); GCubeCollection coll = new GCubeCollection(); coll.setUcd(ucd); // TODO TO Check index flag should be in configuration or evaluated according to // user credentials String toCheckFlag = "internal"; // TODO constant coll.setIndexes(new ArrayList()); LOG.debug("Checking if " + u.getId() + " is GIS Indexed. Index flag needed is " + toCheckFlag); for (Index index : ucdConfig.getIndexes()) { try { IndexLayerDV toAdd = ConvertToDataValueObjectModel.convert(index); if (toAdd.getFlag().equals(toCheckFlag)) { coll.getIndexes().add(toAdd); } } catch (Exception e) { LOG.debug("Skipping invalid index ", e); } catch (Throwable t) { LOG.error("Unable to check index ", t); } } // Return only if gis indexed if (coll.getIndexes().isEmpty()) LOG.info("No available GIS Index for collection " + coll.getUcd().getName()); else config.getAvailableCollections().put(coll.getUcd().getId(), coll); } catch (Throwable t) { LOG.warn("Invalid UCD, can't translate to DV. UCID : " + u.getId(), t); } }); // TODO load initial layers from query parameters LOG.debug("Found " + config.getAvailableCollections().size() + " collections"); return config; } catch (Throwable t) { LOG.error("Unexpected exception while loading initial config", t); throw new ControlledError("Unable to configure viewer. Please retry in a few minutes."); } } }.execute().getResult(); } /** * List of fields for searching. * * @return the list * @throws Exception the exception */ @Override public List listOfFieldsForSearching() throws Exception { LOG.info("listOfFieldsForSearching called"); try { SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); // GNADataViewerConfigProfile profile = getGNADataVieweConfigProfile(); // return profile.getListItemFields(); List listIFResponse = new ArrayList(); List handlersIds = Arrays.asList(GEOPORTAL_DATA_HANDLER.geoportal_data_list.getId()); List listUseCaseDescriptor; try { UseCaseDescriptorCaller client = GeoportalClientCaller.useCaseDescriptors(); listUseCaseDescriptor = client.getListForHandlerIds(handlersIds); } catch (Exception e) { LOG.error("Error on reading handlerIds: " + handlersIds + ", in the UCDs", e); return null; } if (listUseCaseDescriptor == null) { listUseCaseDescriptor = new ArrayList(); } // List listUCDDV = new // ArrayList(listUseCaseDescriptor.size()); for (UseCaseDescriptor ucd : listUseCaseDescriptor) { UseCaseDescriptorDV ucdDV = ConvertToDataValueObjectModel.toUseCaseDescriptorDV(ucd, null); // listUCDDV.add(ucdDV); HandlerDeclarationDV dataListHandler = getHandlerDeclarationFor(ucdDV, GEOPORTAL_DATA_HANDLER.geoportal_data_list); if (dataListHandler != null) { ConfigurationDV config = dataListHandler.getConfiguration(); switch (config.getConfigurationType()) { case item_fields: ItemFieldsResponse ifResponse = new ItemFieldsResponse(); ifResponse.setUseCaseDescriptorDV(ucdDV); List listItemFields = (List) config.getConfiguration(); // map.put(ucdDV.getProfileID(), listItemFields); ifResponse.setListItemFields(listItemFields); listIFResponse.add(ifResponse); break; default: break; } } } LOG.info("listOfFieldsForSearching returning: " + listIFResponse); return listIFResponse; } catch (Exception e) { LOG.error("Error on loading list of fields for searching: ", e); throw new Exception("Error occurred on loading list of fields for searching. Error: " + e.getMessage()); } } /** * Gets the handler declaration for. * * @param useCaseDescriptor the use case descriptor * @param dataHandler the data handler * @return the handler declaration for */ public static HandlerDeclarationDV getHandlerDeclarationFor(UseCaseDescriptorDV useCaseDescriptor, GEOPORTAL_DATA_HANDLER dataHandler) { if (useCaseDescriptor == null) return null; for (HandlerDeclarationDV handler : useCaseDescriptor.getHandlers()) { GEOPORTAL_DATA_HANDLER dataHandlerType = handler.getDataHandlerType(); if (dataHandlerType != null && dataHandlerType.equals(dataHandler)) { return handler; } } return null; } /** * Inits the. * * @param config the config * @throws ServletException the servlet exception */ @Override public void init(ServletConfig config) throws ServletException { super.init(config); LOG.info("init called"); // Init one GcubeProfilesPerUCDIdCache for the application new GcubeProfilesPerUCDIdCache(); } /** * On before request deserialized. * * @param serializedRequest the serialized request */ @Override protected void onBeforeRequestDeserialized(String serializedRequest) { LOG.info("onBeforeRequestDeserialized called"); String scope = ""; try { new GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); scope = SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); // Loading GcubeProfilesPerUCDIdCache per scope GcubeProfilesPerUCDIdCache.get(scope); } catch (Exception e) { LOG.error("Error on loading the " + GcubeProfilesPerUCDIdCache.class.getSimpleName() + " for scope: " + scope, e); e.printStackTrace(); } super.onBeforeRequestDeserialized(serializedRequest); } /** * Gets the list projects. * * @param theProfileID the the profile ID * @param start the start * @param limit the limit * @param filter the filter * @param reloadFromService the reload from service * @return the list projects * @throws Exception the exception */ @Override public ResultSetPaginatedData getListProjects(String theProfileID, Integer start, Integer limit, SearchingFilter filter, boolean reloadFromService) throws Exception { LOG.info("getListProjects called with profileID: " + theProfileID + ", start: " + start + ", limit: " + limit + ", filter: " + filter); try { ProjectsCaller client = GeoportalClientCaller.projects(); SessionUtil.getCurrentContext(getThreadLocalRequest(), true); Integer totalProjectForProfile = SessionUtil.getTotalDocumentForProfileID(getThreadLocalRequest(), theProfileID); if (totalProjectForProfile == null) { totalProjectForProfile = client.getTotalDocument(theProfileID); SessionUtil.setTotalDocumentForProfileID(getThreadLocalRequest(), theProfileID, totalProjectForProfile); } LOG.info("Total Docs read from config: " + totalProjectForProfile); Iterator projects = client.queryOnMongo(theProfileID, totalProjectForProfile, start, limit, filter); ResultSetPaginatedData searchedData = new ResultSetPaginatedData(start, limit, false); searchedData.setTotalItems(totalProjectForProfile); List toReturnList = ConvertToDataValueObjectModel.toListResultDocument(projects); searchedData.setData(toReturnList); // TODO BUGGY WORKAROUND. BLOCKED BY #22487 IT MUST BE REMOVE AFTER THE QUERY // COUNT // AND LIST.SIZE BY QUERY WILL BE AVAILABLE IN THE SERVICE if (filter.getConditions() != null) { searchedData.setTotalItems(toReturnList.size()); int totalItems = toReturnList.size(); searchedData.setTotalItems(totalItems); } if (totalProjectForProfile == limit || totalProjectForProfile == 0) { LOG.debug("Page completed returning " + totalProjectForProfile + " projects"); int newOffset = start + limit; searchedData.setServerSearchFinished(newOffset > totalProjectForProfile || totalProjectForProfile == 0); LOG.debug("is Search finished: " + searchedData.isServerSearchFinished()); } if (LOG.isDebugEnabled()) { LOG.debug("returning {}", searchedData.getData()); } List data = searchedData.getData(); if (data != null) { LOG.info("returning {} project/s", data.size()); } return searchedData; } catch (Exception e) { LOG.error("Error on loading paginated and filtered list of projects for id: ", e); throw new Exception("Error occurred on loading list of Concessioni. Error: " + e.getMessage()); } } /** * Gets the layers for id. * * @param profileID the profile ID * @param projectID the project ID * @return the layers for id * @throws Exception the exception */ @Override public List getLayersForId(String profileID, String projectID) throws Exception { LOG.info("getLayersForId [profileID: " + profileID + ", projectID: " + projectID + "] called"); if (profileID == null) throw new Exception("Invalid parameter. The profileID is null"); if (projectID == null) throw new Exception("Invalid parameter. The projectID is null"); List listLayers = null; try { SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); try { SessionUtil.getCurrentUser(this.getThreadLocalRequest()).getUsername(); } catch (Exception e) { LOG.info("User not found in session, the userName for cecking policy will be null"); } LOG.info("Trying to get project for id " + profileID); new GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID); String jsonDocument = theProject.getTheDocument().toJson(); LOG.trace("JSON Project is: " + jsonDocument); String materializationParentJSONPath = String.format("%s..%s", Geoportal_JSON_Mapper.JSON_$_POINTER, Geoportal_JSON_Mapper.FILESET); listLayers = Geoportal_JSON_Mapper.readGcubeSDILayersForFileset(materializationParentJSONPath, jsonDocument); LOG.info("For projectID " + projectID + ", returning " + listLayers.size() + " layer/s"); return listLayers; } catch (Exception e) { String erroMsg = "Layers are not available for profileID " + profileID + " with projectID " + projectID; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } protected List getImagesForId(String profileID, String projectID) throws Exception { LOG.info("getImagesForId [profileID: " + profileID + ", projectID: " + projectID + "] called"); if (profileID == null) throw new Exception("Invalid parameter. The profileID is null"); if (projectID == null) throw new Exception("Invalid parameter. The projectID is null"); List listImages = null; try { SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); try { SessionUtil.getCurrentUser(this.getThreadLocalRequest()).getUsername(); } catch (Exception e) { LOG.info("User not found in session, the userName for cecking policy will be null"); } LOG.info("Trying to get project for id " + profileID); new GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID); String jsonDocument = theProject.getTheDocument().toJson(); LOG.trace("JSON Project is: " + jsonDocument); String filesetJSONPath = String.format("%s..%s", Geoportal_JSON_Mapper.JSON_$_POINTER, Geoportal_JSON_Mapper.FILESET); listImages = Geoportal_JSON_Mapper.readImagesForFileset(filesetJSONPath, jsonDocument); LOG.info("For projectID " + projectID + ", returning " + listImages.size() + " image/s"); return listImages; } catch (Exception e) { String erroMsg = "Images are not available for profileID " + profileID + " with projectID " + projectID; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * Gets the project view for id. * * @param profileID the profile ID * @param projectID the project ID * @return the project view for id * @throws Exception the exception */ @Override public ProjectView getProjectViewForId(String profileID, String projectID) throws Exception { LOG.info("getProjectForId profileID: " + profileID + ", projectID: " + projectID + "called"); if (profileID == null || projectID == null) throw new Exception("Invalid parameter. Either profileID or projectID is null"); try { String scope = SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); String userName = null; try { userName = SessionUtil.getCurrentUser(this.getThreadLocalRequest()).getUsername(); } catch (Exception e) { LOG.info("User not found in session, the userName for cecking policy will be null"); } LOG.info("Trying to get project for id " + profileID); new GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); UseCaseDescriptor ucd = GeoportalClientCaller.useCaseDescriptors().getUCDForId(profileID); Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID); ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder().fullDocumentMap(true); projectBuilder.relationships(true); ProjectDV theProjectDV = ConvertToDataValueObjectModel.toProjectDV(theProject, projectBuilder); theProjectDV.setProfileName(ucd.getName()); ProjectView projectView = Geoportal_JSON_Mapper.loadProjectView(theProjectDV, scope, userName); if (LOG.isDebugEnabled()) { Geoportal_JSON_Mapper.prettyPrintProjectView(projectView); } LOG.info("returning project view for id: " + projectView.getTheProjectDV().getId()); return projectView; } catch (Exception e) { String erroMsg = "Error occurred on creating projectView for id: " + projectID; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * 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 for layerObjects: " + layerObjects); if (LOG.isDebugEnabled()) { LOG.info("getDataResult parmeters layerObjects: " + layerObjects, ", mapSrsName: " + mapSrsName + ", selectBBOX: " + selectBBOX + ", maxWFSFeature: " + maxWFSFeature + ", zoomLevel: " + zoomLevel); } 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); if (features != null && features.size() > 0) { LayerObjectType loType = layerObject.getType(); if (loType == null) loType = LayerObjectType.GENERIC_LAYER; switch (layerObject.getType()) { case INDEX_LAYER: { // Expected 1 feature FeatureRow fRow = features.get(0); if (fRow.getMapProperties() != null) { List productIDs = fRow.getMapProperties().get("projectid"); if (productIDs != null && productIDs.size() > 0) { String projectID = productIDs.get(0); layerObject.setProjectID(projectID); String profileID = layerObject.getProfileID(); List images; // Loading images for profileID and projectID try { images = getImagesForId(profileID, projectID); Map> mapImages = new LinkedHashMap>(); mapImages.put(projectID, images); // mapImages.put(cId, listUI); geoDAO.setMapImages(mapImages); } catch (Exception e) { LOG.warn("Error on loading images for projectID: " + projectID + " profileID: " + profileID); } } } geoDAO.setSourceLayerObject(layerObject); LOG.info("For layer name: " + layerObject.getLayerItem().getName() + " got " + features.size() + " feature/s"); listDAO.add(geoDAO); break; } case PROJECT_LAYER: case GENERIC_LAYER: { // Getting the projectid from WFS features, but limiting to the first one for (FeatureRow fRow : features) { if (fRow.getMapProperties() != null) { List productIDs = fRow.getMapProperties().get("projectid"); if (productIDs != null && productIDs.size() > 0) { String projectID = productIDs.get(0); layerObject.setProjectID(projectID); String profileID = layerObject.getProfileID(); try { Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID); ProjectDVBuilder projectBuilder = ProjectDVBuilder.newBuilder() .fullDocumentMap(false); ProjectDV projectDV = ConvertToDataValueObjectModel.toProjectDV(theProject, projectBuilder); geoDAO.setProjectDV(projectDV); layerObject.setProjectDV(projectDV); // Limiting to 1 feature of Layers continue; } catch (Exception e) { LOG.warn("Error on loading the Project for projectID: " + projectID + " profileID: " + profileID); } } } } geoDAO.setSourceLayerObject(layerObject); LOG.info("For layer name: " + layerObject.getLayerItem().getName() + " got " + features.size() + " feature/s"); listDAO.add(geoDAO); } default: break; } } } LOG.info("returning " + listDAO + " geona data objects"); return listDAO; } }