package org.gcube.portlets.user.geoportaldataviewer.server; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.bson.Document; import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.common.model.useCaseDescriptor.HandlerDeclaration; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportalcommon.ConvertToDataValueObjectModel; import org.gcube.application.geoportalcommon.GeoportalCommon; import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; import org.gcube.application.geoportalcommon.geoportal.UseCaseDescriptorCaller; import org.gcube.application.geoportalcommon.geoportal.access.GeportalCheckAccessPolicy; import org.gcube.application.geoportalcommon.geoportal.serdes.Payload; import org.gcube.application.geoportalcommon.shared.GNADataViewerConfigProfile; import org.gcube.application.geoportalcommon.shared.GeoNaItemRef; 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.config.FilePathDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.GcubeProfileDV; import org.gcube.application.geoportalcommon.shared.geoportal.config.ItemFieldDV; import org.gcube.application.geoportalcommon.shared.geoportal.project.ProjectDV; import org.gcube.application.geoportalcommon.shared.geoportal.ucd.GEOPORTAL_CONFIGURATION_TYPE; 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.view.FilesetDV; import org.gcube.application.geoportalcommon.shared.geoportal.view.PayloadDV; import org.gcube.application.geoportalcommon.shared.geoportal.view.ProjectView; import org.gcube.application.geoportalcommon.shared.geoportal.view.SectionView; import org.gcube.application.geoportalcommon.shared.geoportal.view.SubDocumentView; 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.mongoservice.GeoportalServiceIdentityProxy; 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.BaseMapLayer; 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.portlets.user.urlshortener.UrlShortener; import org.gcube.portlets.widgets.mpformbuilder.server.MetadataProfileFormBuilderServiceImpl; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetaDataProfileBean; import org.gcube.portlets.widgets.mpformbuilder.shared.metadata.MetadataFieldWrapper; 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.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider; /** * 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); private static final String CACHE_IMAGE_PREVIEW_FOR_CONCESSIONE = "MAP_IMAGE_PREVIEW_FOR_CONCESSIONE"; public static final String JSON_$_POINTER = "$"; public static enum COMMON_IMAGES_FORMAT { gif, png, jpeg, jpg, bmp, tif, tiff, svg, avif, webp } public static class ImageDetector { 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); } 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 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); // Getting the concessioneId from WFS 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 { UploadedImageDV uplImg = sessionloadPreviewImageForConcessione(this.getThreadLocalRequest(), "Concessione", cId); // List listUI = getUploadedImagesForId("Concessione", cId, 1); Map> mapImages = new LinkedHashMap>(); mapImages.put(cId, Arrays.asList(uplImg)); // 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, 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 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, 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; } // TODO THIS PART REQUIRES THE JSON MAPPING based on keys read from gCube Meta /** * List of fields for searching. * * @return the list * @throws Exception the exception */ @Override public List listOfFieldsForSearching() throws Exception { LOG.info("listOfFieldsForSearching called"); SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true); GNADataViewerConfigProfile profile = getGNADataVieweConfigProfile(); return profile.getListItemFields(); } /** * * * * * * * * * * * * * * * NEW CODE HERE * * * * * * * * * * * * * */ /** * Gets the list concessioni. * * @param start the start * @param limit the limit * @param filter the filter * @param reloadFromService the reload from service * @return the list concessioni * @throws Exception the exception */ @Override public ResultSetPaginatedData getListConcessioni(Integer start, Integer limit, SearchingFilter filter, boolean reloadFromService) throws Exception { LOG.info("getListConcessioni called wit start: " + start + ", limit: " + limit + ", filter: " + filter); try { throw new Exception("getListConcessioni must be revisited!!!!"); /* * * // setting identity as D4S User or KC client new * GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); * SessionUtil.getCurrentContext(getThreadLocalRequest(), true); * MongoServiceCommon serviceCommon = new MongoServiceCommon(); // TODO MUST BE * REPLACED BY COUNT List listOfConcessioni = * SessionUtil.getListOfConcessioni(getThreadLocalRequest(), reloadFromService); * int listConcessioniSize = listOfConcessioni.size(); * * ResultSetPaginatedData searchedData = * serviceCommon.queryOnMongo(listConcessioniSize, start, limit, filter, * "concessione"); return searchedData; */ } catch (Exception e) { LOG.error("Error on loading paginated and filtered list of concessioni: ", e); throw new Exception("Error occurred on loading list of Concessioni. Error: " + e.getMessage()); } } /** * Preloadg cube profiles for UC ds. */ public void preloadgCubeProfilesForUCDs() { LOG.info("preloadgCubeProfilesForUCDs called"); try { String currentContext = SessionUtil.getCurrentContext(getThreadLocalRequest(), true); LOG.info("preloadgCubeProfilesForUCDs context: "+currentContext); UseCaseDescriptorCaller clientUCD = GeoportalClientCaller.useCaseDescriptors(); SessionUtil.getCurrentContext(getThreadLocalRequest(), true); List listUCDs = clientUCD.getList(); LOG.debug("listUCDs: "+listUCDs); for (UseCaseDescriptor ucd : listUCDs) { LOG.info("Loaded UCD for ID: " + ucd.getId()); String profileID = ucd.getId(); GEOPORTAL_DATA_HANDLER theHandler = GEOPORTAL_DATA_HANDLER.geoportal_data_entry; List handlers = ucd.getHandlersByType(theHandler.getType()); if (handlers.size() == 0) { LOG.warn("No handler " + theHandler + "found into UCD " + ucd.getId() + ", continue..."); continue; } // Loading Handler gcube_profiles HandlerDeclaration dataEntryHandler = handlers.get(0); HandlerDeclarationDV handlerGcubeProfiles = ConvertToDataValueObjectModel .toHandlerDeclarationDV(dataEntryHandler, ucd, GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles); LOG.debug("Handler " + GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles + " for PROFILE_ID: " + ucd.getId()); LOG.debug("" + handlerGcubeProfiles); ConfigurationDV config = handlerGcubeProfiles.getConfiguration(); // List of gCube Profiles defined in the UCD List listGcubeProfiles = (List) config.getConfiguration(); LOG.debug("List of GcubeProfileDV are: " + listGcubeProfiles); List listProfilesBean = new ArrayList(); // Loading Metadata Profile from IS MetadataProfileFormBuilderServiceImpl metaProfileBUilder = new MetadataProfileFormBuilderServiceImpl(); LinkedHashMap> linkedMap_UCDId_gCubeProfiles = new LinkedHashMap>(); for (GcubeProfileDV gcubeProfileDV : listGcubeProfiles) { String context = SessionUtil.getCurrentContext(getThreadLocalRequest(), true); GcubeProfilesMetadataForUCD gCubeProfileMetadataForUCD = new GcubeProfilesMetadataForUCD(); List listProfiles = metaProfileBUilder.getProfilesInTheScopeForName(context, gcubeProfileDV.getGcubeSecondaryType(), gcubeProfileDV.getGcubeName()); String key = gcubeProfileDV.getGcubeSecondaryType() + gcubeProfileDV.getGcubeName(); LOG.debug("for key: " + key + " readi profiles: " + listGcubeProfiles); gCubeProfileMetadataForUCD.setGcubeProfile(gcubeProfileDV); gCubeProfileMetadataForUCD.setListMetadataProfileBean(listProfiles); listProfilesBean.add(gCubeProfileMetadataForUCD); } linkedMap_UCDId_gCubeProfiles.put(ucd.getId(), listProfilesBean); for (String key : linkedMap_UCDId_gCubeProfiles.keySet()) { LOG.debug("For key '" + key + "' got profiles: " + linkedMap_UCDId_gCubeProfiles.get(key)); } SessionUtil.setMap_UCDId_gCubeProfiles(getThreadLocalRequest(), profileID, linkedMap_UCDId_gCubeProfiles); } } catch (Exception e) { String erroMsg = "Error occurred on preloadgCubeProfilesForUCDs: "; LOG.error(erroMsg, e); } } /** * 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"); throw new Exception("getLayersForId 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 listLayers = null; * * try { * * 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" * ); } * * if (itemType.equalsIgnoreCase("concessione")) { * * LOG.info("Trying to get concessione for id " + itemId); * GeoportalServiceIdentityProxy cms = new * GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); Concessione * concessione = cms.getItemById(itemId); * * BaseConcessioneDV baseConcessione = * ConvertToDataViewModel.toBaseConcessione(concessione); 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()) { if * (GeoNACheckAccessPolicy.isAccessible(lc.getPolicy().name(), userName)) { * listLayers.add(ConvertToDataViewModel.toLayerConcessione(lc, * baseConcessione)); } } * * LayerConcessione lcPosizionamento = concessione.getPosizionamentoScavo(); * * if (lcPosizionamento != null) { * * if (GeoNACheckAccessPolicy.isAccessible(lcPosizionamento.getPolicy().name(), * userName)) { * * LayerConcessioneDV thePosizScavo = ConvertToDataViewModel * .toLayerConcessione(lcPosizionamento, baseConcessione); 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 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 { 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); GeoportalServiceIdentityProxy cms = new GeoportalServiceIdentityProxy(this.getThreadLocalRequest()); ProjectDV theProjectDV = cms.getProjectByID(profileID, projectID); String theWholeProjectAsJSON = theProjectDV.getTheDocument().getDocumentAsJSON(); LOG.debug("theProjectDV as JSON: " + theWholeProjectAsJSON); LOG.debug("theProjectDV as MAP: " + theProjectDV.getTheDocument().getDocumentAsMap()); ProjectView projectView = new ProjectView(); projectView.setTheProjectDV(theProjectDV); LinkedHashMap> linkedMap_UCDId_gCubeProfiles = SessionUtil .getMap_UCDId_gCubeProfiles(getThreadLocalRequest(), profileID); if(linkedMap_UCDId_gCubeProfiles==null) { preloadgCubeProfilesForUCDs(); linkedMap_UCDId_gCubeProfiles = SessionUtil .getMap_UCDId_gCubeProfiles(getThreadLocalRequest(), profileID); } // NO UCD defined, applyong default if (linkedMap_UCDId_gCubeProfiles.size() == 0) { LOG.warn("No " + GEOPORTAL_CONFIGURATION_TYPE.gcube_profiles + " found in the UCD"); LOG.info("Applying default business logic to display the project"); SectionView sectionView = new SectionView(); sectionView.setSectionTitle("Document"); SubDocumentView subDocumentView = new SubDocumentView(); subDocumentView.setMetadataAsJSON(theProjectDV.getTheDocument().getDocumentAsJSON()); sectionView.addSubDocument(subDocumentView); projectView.addSectionView(sectionView); } List listProfilesBean = linkedMap_UCDId_gCubeProfiles.get(profileID); com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() .jsonProvider(new JsonOrgJsonProvider()).build(); // Reading the Project according to list of Profile defined in the UCD for (GcubeProfilesMetadataForUCD gcubeProfileMetaForUCD : listProfilesBean) { GcubeProfileDV gcubeProfileDV = gcubeProfileMetaForUCD.getGcubeProfile(); SectionView sectionView = new SectionView(); sectionView.setSectionTitle(gcubeProfileDV.getSectionTitle()); LOG.debug("\n\nThe profile is: " + gcubeProfileDV); // Building JSON/section full PATH and section name String sectionJSONPath = ""; String parentPathFromProfile = gcubeProfileDV.getParentName() == null ? "" : gcubeProfileDV.getParentName(); String theSectionName = gcubeProfileDV.getSectionName(); if (theSectionName.compareTo(JSON_$_POINTER) == 0 || theSectionName.compareTo(JSON_$_POINTER + ".") == 0) { sectionJSONPath = JSON_$_POINTER; theSectionName = ""; } else { sectionJSONPath = String.format("%s%s", parentPathFromProfile.endsWith(".") ? parentPathFromProfile : parentPathFromProfile + ".", theSectionName); } LOG.debug("The sectionJSONPath is: " + sectionJSONPath); JsonPath theSectionJsonPath = JsonPath.compile(sectionJSONPath); Object data = theSectionJsonPath.read(theWholeProjectAsJSON, configuration); LOG.debug("Data is instace of: " + data.getClass()); LOG.debug("data to string: " + data.toString()); // Splitting the General Document in bson.Document according to list of // GcubeProfiles List listBSONDocument = new ArrayList(); if (data instanceof org.json.JSONObject) { String jsonString = data.toString(); LOG.debug("the JSON to string: " + jsonString); Document sectionDoc = Document.parse(jsonString); boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, sectionJSONPath, userName); if (isAccessibleSection) { listBSONDocument.add(sectionDoc); } } else if (data instanceof org.json.JSONArray) { org.json.JSONArray dataArray = (org.json.JSONArray) data; for (int i = 0; i < dataArray.length(); i++) { String jsonString = dataArray.get(i).toString(); LOG.debug("the array " + i + " JSON to string: " + jsonString); Document sectionDoc = Document.parse(jsonString); boolean isAccessibleSection = isAccessibleSectionAccordingToPolicy(sectionDoc, sectionJSONPath, userName); if (isAccessibleSection) { listBSONDocument.add(sectionDoc); } } } LOG.debug("Result for " + gcubeProfileDV.getSectionName() + " is: " + listBSONDocument); List theProfileBeans = gcubeProfileMetaForUCD.getListMetadataProfileBean(); MetaDataProfileBean theProfileBean = theProfileBeans.get(0); // For each bson.Document creating the SubDocumentView for (int i = 0; i < listBSONDocument.size(); i++) { Document fromSectionDoc = listBSONDocument.get(i); SubDocumentView subDocumentView = new SubDocumentView(); Document toSectionDoc = new Document(); // Filling the SubDocumentView metadata with the metadataField.getFieldName() // read from the Profile for (MetadataFieldWrapper metadataField : theProfileBean.getMetadataFields()) { String theFieldName = metadataField.getFieldId() != null ? metadataField.getFieldId() : metadataField.getFieldName(); LOG.debug("reading theFieldName: " + theFieldName); Object theOBJFieldValue = fromSectionDoc.get(theFieldName); // NB: Using ALWAYS THE metadataField.getFieldName() as LABEL toSectionDoc = sanitizeDocumentValue(toSectionDoc, metadataField.getFieldName(), theOBJFieldValue); } String subToJSON = toSectionDoc.toJson(); LOG.debug("theSubSetionDoc is: " + subToJSON); subDocumentView.setMetadataAsJSON(toSectionDoc.toJson()); // Reading filePaths List filePaths = gcubeProfileDV.getFilePaths(); // READING fileset* field ACCORDING TO filePaths OF THE 'gcubeProfiles' CONFIG if (filePaths != null) { String fromSectionDocJSON = fromSectionDoc.toJson(); List listFiles = new ArrayList(); List listImages = new ArrayList(); for (FilePathDV filePath : filePaths) { String filesetJSONPath = String.format("%s.%s", JSON_$_POINTER, filePath.getFieldName()); List listPayloads = readPayloadsForFileset(filesetJSONPath, fromSectionDocJSON); FilesetDV filesetDV = new FilesetDV(); filesetDV.setName(filePath.getGcubeProfileFieldName()); for (Payload payload : listPayloads) { PayloadDV payloadDV = ConvertToDataValueObjectModel.toPayloadDV(payload); filesetDV.addPayloadDV(payloadDV); boolean isImage = ImageDetector.isImage(payload.getMimetype()); if (isImage) { listImages.add(filesetDV); } else { listFiles.add(filesetDV); } } } subDocumentView.setListFiles(listFiles); subDocumentView.setListImages(listImages); } sectionView.addSubDocument(subDocumentView); } projectView.addSectionView(sectionView); } // for (SectionView section : projectView.getListSections()) { // System.out.println("\n\n###### Section Title: " + section.getSectionTitle() + " ######"); // int i = 1; // for (SubDocumentView subDocument : section.getListSubDocuments()) { // System.out.println("## " + SubDocumentView.class.getSimpleName() + " n." + i); // System.out.println("***** Metadata"); // System.out.println(prettyPrintJSON(subDocument.getMetadataAsJSON())); // System.out.println("***** Files"); // if (subDocument.getListFiles() != null) { // for (FilesetDV filesetDV : subDocument.getListFiles()) { // System.out.println("******* File Fileset name: " + filesetDV.getName()); // for (PayloadDV payload : filesetDV.getListPayload()) { // System.out.println("********* Payload: " + payload); // } // } // } // System.out.println("***** Images"); // if (subDocument.getListImages() != null) { // for (FilesetDV filesetDV : subDocument.getListImages()) { // System.out.println("******* Image Fileset name: " + filesetDV.getName()); // for (PayloadDV payload : filesetDV.getListPayload()) { // System.out.println("********* Payload: " + payload); // } // } // } // i++; // } // // } return projectView; } catch (Exception e) { String erroMsg = "Error occurred on creating projectView for id: " + projectID; LOG.error(erroMsg, e); throw new Exception(erroMsg); } } /** * Read payloads for fileset. * * @param filesetJSONPath the fileset JSON path * @param sectionJSONDocument the section JSON document * @return the list */ private List readPayloadsForFileset(String filesetJSONPath, String sectionJSONDocument) { LOG.debug("readPayloadsForFileset called"); List listPayloads = new ArrayList(); String _payloadsJSONPath = String.format("%s.%s", filesetJSONPath, "_payloads"); try { com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() .jsonProvider(new JsonOrgJsonProvider()).build(); LOG.info("Reading sectionPath at {} into section document {}", _payloadsJSONPath, sectionJSONDocument); JsonPath theSectionPolycJsonPath = JsonPath.compile(_payloadsJSONPath); Object _payloads = theSectionPolycJsonPath.read(sectionJSONDocument, configuration).toString(); if (_payloads instanceof String) { String toStringPayloads = (String) _payloads; LOG.trace("The _payloads is a String {}", toStringPayloads); JSONArray jsonArray = new JSONArray(toStringPayloads); for (int i = 0; i < jsonArray.length(); i++) { Payload payloadDV = Serialization.read(jsonArray.getJSONObject(i).toString(), Payload.class); listPayloads.add(payloadDV); } } LOG.info("returning list of payloads {}", listPayloads); } catch (Exception e) { LOG.error("Error on reading the JSON Path {} in the doc {} ", _payloadsJSONPath, sectionJSONDocument); e.printStackTrace(); } return listPayloads; } /** * Checks if is accessible section according to policy. * * @param section the section * @param sectionJSONPath the section JSON path * @param myLogin the my login * @return true, if is accessible section according to policy */ private boolean isAccessibleSectionAccordingToPolicy(Document section, String sectionJSONPath, String myLogin) { LOG.debug("isAccessibleSectionAccordingToPolicy called"); boolean isAccessible = true; // Skipping the root, going to check the access_policy of subsections if (sectionJSONPath.compareTo(JSON_$_POINTER) != 0) { isAccessible = checkAccessPolicy(section.toJson(), myLogin); } return isAccessible; } /** * Check access policy. * * @param sectionDocumentJSON the section document JSON * @param myLogin the my login * @return true, if successful */ private boolean checkAccessPolicy(String sectionDocumentJSON, String myLogin) { LOG.debug("checkAccessPolicy called"); // CHECKING THE POLICY String accessPolicyPath = JSON_$_POINTER + "._access._policy"; boolean isAccessible = true; try { com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() .jsonProvider(new JsonOrgJsonProvider()).build(); LOG.info("Reading access policy at {} into section document {}", accessPolicyPath, sectionDocumentJSON); JsonPath theSectionPolycJsonPath = JsonPath.compile(accessPolicyPath); String _policy = theSectionPolycJsonPath.read(sectionDocumentJSON, configuration).toString(); LOG.info("The section {} has policy {}", accessPolicyPath, _policy); isAccessible = GeportalCheckAccessPolicy.isAccessible(_policy, myLogin); } catch (Exception e) { LOG.error(accessPolicyPath + " not found. Check OK"); } LOG.info("Is the section {} accessible? {}", sectionDocumentJSON, isAccessible); return isAccessible; } /** * Pretty print JSON. * * @param jsonString the json string * @return the string */ private String prettyPrintJSON(String jsonString) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonObject jsonObject = new JsonParser().parse(jsonString).getAsJsonObject(); return gson.toJson(jsonObject); } /** * Sanitize document value. * * @param toDoc the to doc * @param fieldLabel the field label * @param theObjectFieldValue the the object field value * @return the document */ private Document sanitizeDocumentValue(Document toDoc, String fieldLabel, Object theObjectFieldValue) { if (theObjectFieldValue != null) { if (theObjectFieldValue instanceof String) { String toString = (String) theObjectFieldValue; if (toString != null && !toString.isEmpty()) { toDoc.append(fieldLabel, theObjectFieldValue); } else { LOG.debug("Skipping String field " + fieldLabel + " its value is null or empty"); } } else if (theObjectFieldValue instanceof ArrayList) { ArrayList toArrayList = (ArrayList) theObjectFieldValue; if (toArrayList != null && !toArrayList.isEmpty()) { toDoc.append(fieldLabel, theObjectFieldValue); } else { LOG.debug("Skipping ArrayList field " + fieldLabel + " its value is null or empty"); } } else { toDoc.append(fieldLabel, theObjectFieldValue); } } else { LOG.debug("Skipping field " + fieldLabel + " its value is null or empty"); } return toDoc; } }