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

1343 lines
48 KiB
Java

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 java.util.Map.Entry;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
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.document.identification.IdentificationReference;
import org.gcube.application.geoportal.common.model.document.relationships.Relationship;
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.geojson.GeoJSON;
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.IdentificationReferencesTYPE;
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.GeoportalDataViewerConstants;
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.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.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
/**
* 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 {
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<? extends Enum<?>> e) {
return Arrays.stream(e.getEnumConstants()).map(Enum::name).toArray(String[]::new);
}
public static List<String> 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<String, String> mapWmsNotStandard = new HashMap<String, String>();
if (validator.getMapWmsNoStandardParams() != null) {
mapWmsNotStandard.putAll(validator.getMapWmsNoStandardParams());
}
//
GeoNcWMSMetadataUtility geoGS = new GeoNcWMSMetadataUtility(validWMSRequest, 4000);
// STYLES
LayerStyles layerStyle = geoGS.loadStyles();
Map<String, String> mapNcWmsStyles = layerStyle.getMapNcWmsStyles() == null ? new HashMap<String, String>(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<UploadedImageDV> getUploadedImagesForId(String itemType, String itemId, Integer maxImages)
throws Exception {
LOG.info("getUploadedImagesForId [itemId: " + itemId + ", itemType: " + itemType + "] called");
throw new Exception("getUploadedImagesForId must be removed!");
}
/**
* 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<LayerConcessioneDV> listLayersDV = concessionDV.getPianteFineScavo(); if
* (listLayersDV != null) { List<LayerConcessioneDV> accessibleListLayersDV =
* new ArrayList<LayerConcessioneDV>(); 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<UploadedImageDV> immagini = concessionDV.getImmaginiRappresentative();
* if (immagini != null && immagini.size() > 0) { List<UploadedImageDV>
* accessibleListImages = new ArrayList<UploadedImageDV>();
*
* // 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<String, String> getParametersFromURL(String theURL, List<String> parameters) {
if (theURL == null)
return null;
if (parameters == null || parameters.size() == 0)
return null;
Map<String, String> hashParameters = new HashMap<String, String>(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<GeoNaSpatialQueryResult> getWFSFeatures(List<LayerObject> layerObjects, String mapSrsName,
BoundsMap selectBBOX, int maxWFSFeature, double zoomLevel) {
LOG.info("getWFSFeatures called");
List<GeoNaSpatialQueryResult> listDAO = new ArrayList<GeoNaSpatialQueryResult>(layerObjects.size());
for (LayerObject layerObject : layerObjects) {
GeoNaSpatialQueryResult geoDAO = new GeoNaSpatialQueryResult();
List<FeatureRow> 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 list base layers.
*
* @return the list base layers
*/
@Override
public List<BaseMapLayer> getListBaseLayers() {
LOG.info("getListBaseLayers called");
List<BaseMapLayer> listBL = new ArrayList<BaseMapLayer>();
// 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<ViewerConfiguration>(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<BaseMapLayer> 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<String, GCubeCollection>());
// 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<Project> 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 indexFlag = "public"; // default
GeoportalServiceIdentityProxy gsp = getGeoportalServiceProxy();
if (gsp.isUser()) {
indexFlag = "internal";
LOG.info("user logged - using indexFlag: " + indexFlag);
} else if (gsp.isIAMClient()) {
indexFlag = "public";
LOG.info("user not logged - using indexFlag: " + indexFlag);
}
// TODO constant
coll.setIndexes(new ArrayList());
LOG.debug(
"Checking if " + u.getId() + " is GIS Indexed. Index flag needed is " + indexFlag);
for (Index index : ucdConfig.getIndexes()) {
try {
IndexLayerDV toAdd = ConvertToDataValueObjectModel.convert(index);
if (toAdd.getFlag().equals(indexFlag)) {
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();
}
/**
* Gets the config list of fields for searching.
*
* @return the config list of fields for searching
* @throws Exception the exception
*/
@Override
public List<ItemFieldsResponse> getConfigListOfFieldsForSearching() throws Exception {
LOG.info("listOfFieldsForSearching called");
try {
SessionUtil.getCurrentContext(this.getThreadLocalRequest(), true);
List<ItemFieldsResponse> listIFResponse = new ArrayList<ItemFieldsResponse>();
List<String> handlersIds = Arrays.asList(GEOPORTAL_DATA_HANDLER.geoportal_basic_data_list.getId());
List<UseCaseDescriptor> 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<UseCaseDescriptor>();
}
for (UseCaseDescriptor ucd : listUseCaseDescriptor) {
UseCaseDescriptorDV ucdDV = ConvertToDataValueObjectModel.toUseCaseDescriptorDV(ucd, null);
HandlerDeclarationDV dataListHandler = getHandlerDeclarationFor(ucdDV,
GEOPORTAL_DATA_HANDLER.geoportal_basic_data_list);
if (dataListHandler != null) {
ConfigurationDV<?> config = dataListHandler.getConfiguration();
switch (config.getConfigurationType()) {
case item_fields:
ItemFieldsResponse ifResponse = new ItemFieldsResponse();
ifResponse.setUseCaseDescriptorDV(ucdDV);
List<ItemFieldDV> listItemFields = (List<ItemFieldDV>) config.getConfiguration();
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);
}
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<Project> projects = client.queryOnMongo(theProfileID, totalProjectForProfile, start, limit,
filter);
ResultSetPaginatedData searchedData = new ResultSetPaginatedData(start, limit, false);
searchedData.setTotalItems(totalProjectForProfile);
List<ResultDocumentDV> 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<? extends DocumentDV> 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<GCubeSDIViewerLayerDV> 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<GCubeSDIViewerLayerDV> 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);
}
}
/**
* Gets the images for id.
*
* @param profileID the profile ID
* @param projectID the project ID
* @param limitToFirstOneFound the limit to first one found
* @return the images for id
* @throws Exception the exception
*/
protected List<PayloadDV> getImagesForId(String profileID, String projectID, boolean limitToFirstOneFound)
throws Exception {
LOG.info("getImagesForId [profileID: " + profileID + ", projectID: " + projectID + ", limitToFirstOneFound: "
+ limitToFirstOneFound + "] 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<PayloadDV> 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,
limitToFirstOneFound);
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.isTraceEnabled()) {
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
* @throws Exception the exception
*/
@Override
public List<GeoNaSpatialQueryResult> getDataResult(List<LayerObject> layerObjects, String mapSrsName,
BoundsMap selectBBOX, int maxWFSFeature, double zoomLevel) throws Exception {
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<GeoNaSpatialQueryResult> listDAO = new ArrayList<GeoNaSpatialQueryResult>(layerObjects.size());
try {
new GeoportalServiceIdentityProxy(this.getThreadLocalRequest());
for (LayerObject layerObject : layerObjects) {
GeoNaSpatialQueryResult geoDAO = new GeoNaSpatialQueryResult();
List<FeatureRow> 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<String> productIDs = fRow.getMapProperties()
.get(GeoportalDataViewerConstants.PROJECT_ID_KEY_FEATURE);
if (productIDs != null && productIDs.size() > 0) {
String projectID = productIDs.get(0);
layerObject.setProjectID(projectID);
String profileID = layerObject.getProfileID();
List<PayloadDV> images;
// Loading images for profileID and projectID
try {
images = getImagesForId(profileID, projectID, true);
Map<String, List<PayloadDV>> mapImages = new LinkedHashMap<String, List<PayloadDV>>();
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);
}
// Sets only profileID and profileName into ProjectDV
if (layerObject.getProjectDV() == null) {
ProjectDV projectDV = minimalProjectDV(profileID, projectID);
layerObject.setProjectDV(projectDV);
}
}
}
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: {
LOG.debug("The LayerObject is a of kind: " + layerObject.getType());
// TODO CHECK THIS
// Getting the projectid from WFS features, but limiting to the first one, Do we
// have more than one centroid in the same position??
// Mininal set of info for displaying into popup
if (layerObject.getProjectDV() == null) {
ProjectDV projectDV = minimalProjectDV(layerObject.getProfileID(),
layerObject.getProjectID());
layerObject.setProjectDV(projectDV);
}
if (layerObject.getProjectDV().getSpatialReference() == null) {
GeoJSON geoJson = spatialReference(layerObject.getProfileID(), layerObject.getProjectID());
layerObject.getProjectDV().setSpatialReference(geoJson);
}
if (layerObject.getProjectDV().getTheDocument() == null) {
try {
LinkedHashMap<String, Object> documentAsMap = getEntrySetsDocumentForProjectID(
layerObject.getProfileID(), layerObject.getProjectID(), 1);
DocumentDV documentDV = new DocumentDV();
documentDV.setDocumentAsMap(documentAsMap);
layerObject.getProjectDV().setTheDocument(documentDV);
} catch (Exception e) {
String erroMsg = "Error occurred on loading document for profileID "
+ layerObject.getProfileID() + " and projectID " + layerObject.getProjectID();
LOG.warn(erroMsg, e);
}
}
LOG.debug("Case PROJECT_LAYER/GENERIC_LAYER setting layerObject: " + layerObject);
geoDAO.setSourceLayerObject(layerObject);
LOG.info("For layer name: " + layerObject.getLayerItem().getName() + " got " + features.size()
+ " feature/s");
listDAO.add(geoDAO);
}
default:
break;
}
}
}
} catch (Exception e) {
String erroMsg = "Error occurred on getting data results";
LOG.error(erroMsg, e);
throw new Exception(erroMsg);
}
LOG.info("returning " + listDAO + " geona data objects");
return listDAO;
}
/**
* Minimal project DV.
*
* @param profileID the profile ID
* @param projectID the project ID
* @return the project DV
*/
private ProjectDV minimalProjectDV(String profileID, String projectID) {
LOG.trace("minimalProjectDV for profileID: " + profileID + ", projectID: " + projectID + "called");
QueryRequest request = new QueryRequest();
request.setFilter(
Document.parse("{\"" + UseCaseDescriptor.ID + "\" : " + "{\"$eq\" : \"" + profileID + "\"}}"));
request.setProjection(Document.parse("{\"" + UseCaseDescriptor.NAME + "\" : " + "1}"));
ProjectDV projectDV = new ProjectDV();
try {
useCaseDescriptors().build().query(request).forEachRemaining(u -> {
try {
LOG.debug("UCD for id" + u.getId() + " returend name: " + u.getName());
projectDV.setId(projectID);
projectDV.setProfileName(u.getName());
projectDV.setProfileID(u.getId());
} catch (Exception e) {
LOG.warn("Invalid UCD, UCID : " + u.getId());
}
});
} catch (Exception e) {
// silent
}
return projectDV;
}
/**
* Spatial reference.
*
* @param profileID the profile ID
* @param projectID the project ID
* @return the geo JSON
*/
private GeoJSON spatialReference(String profileID, String projectID) {
LOG.trace("spatialReference for profileID: " + profileID + ", projectID: " + projectID + "called");
try {
List<IdentificationReference> listIR = projects(profileID).build().getById(projectID)
.getIdentificationReferenceByType(IdentificationReferencesTYPE.SPATIAL_REFERENCE.getType());
if (listIR != null && !listIR.isEmpty()) {
String _identificationReferenceString = listIR.get(0).toJson(); // one expected
LOG.debug("converting for profileID: " + profileID + ", projectID: " + projectID + "called");
return ConvertToDataValueObjectModel.toSpatialReference(_identificationReferenceString);
}
} catch (Exception e1) {
// silent
}
return new GeoJSON();
}
/**
* Gets the entry sets document for project ID.
*
* @param profileID the profile ID
* @param projectID the project ID
* @param limit the limit
* @return the entry sets document for project ID
*/
@Override
public LinkedHashMap<String, Object> getEntrySetsDocumentForProjectID(String profileID, String projectID,
int limit) {
LinkedHashMap<String, Object> documentAsMap = new LinkedHashMap<String, Object>(limit);
try {
Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID);
try {
Iterator<Entry<String, Object>> entrySetsIt = theProject.getTheDocument().entrySet().iterator();
int i = 0;
while (entrySetsIt.hasNext()) {
if (i > limit)
break;
Entry<String, Object> entry = entrySetsIt.next();
documentAsMap.put(entry.getKey(), entry.getValue());
i++;
}
} catch (Exception e) {
throw e;
}
return documentAsMap;
} catch (Exception e) {
String erroMsg = "Error occurred on loading EntrySets document for profileID " + profileID
+ " and projectID " + projectID;
LOG.warn(erroMsg, e);
}
return documentAsMap;
}
@Override
public List<String> getRelationshipsForTimeline(String profileID, String projectID) throws Exception {
if (profileID == null || projectID == null)
throw new Exception("Invalid parameter. Either profileID or projectID is null");
try {
LOG.info("Trying to getRelationshipsForTimeline for id " + profileID);
List<String> listJSON = new ArrayList<String>();
try {
String template = "{\"content\": \"$._theDocument.nome\","
+ "\"start\" : \"$._theDocument.dataInizioProgetto\","
+ "\"end\" : \"$._theDocument.dataFineProgetto\"}";
JSONObject sourceJsonTemplate = new JSONObject(template);
JSONObject targetJsonObject = new JSONObject();
com.jayway.jsonpath.Configuration conf = com.jayway.jsonpath.Configuration.defaultConfiguration();
com.jayway.jsonpath.Configuration conf2 = conf.addOptions(Option.ALWAYS_RETURN_LIST);
Project theProject = GeoportalClientCaller.projects().getProjectByID(profileID, projectID);
List<Relationship> relationships = theProject.getRelationships();
for (Relationship relationship : relationships) {
targetJsonObject.put("id", relationship.getTargetUCD()+","+relationship.getTargetID());
Project targetProject = GeoportalClientCaller.projects().getProjectByID(relationship.getTargetUCD(),
relationship.getTargetID());
DocumentContext targetDoc = JsonPath.using(conf2).parse(targetProject.getTheDocument().toJson());
for (Object key : sourceJsonTemplate.keySet()) {
String theKey = key + "";
String jsonPath = sourceJsonTemplate.getString(theKey);
// Works fine
List<String> listValue = targetDoc.read(jsonPath);
String result = "";
for (int i = 0; i < listValue.size() - 1; i++) {
result += listValue.get(i) + ", ";
}
result += listValue.get(listValue.size() - 1);
targetJsonObject.put(theKey, result);
}
List<PayloadDV> images = getImagesForId(relationship.getTargetUCD(), relationship.getTargetID(),
true);
if (images.size() > 0) {
images.get(0).getLink();
targetJsonObject.put("image_url", images.get(0).getLink());
}
String theJSONResult = targetJsonObject.toString();
LOG.debug("Built jsonObject " + theJSONResult);
listJSON.add(theJSONResult);
}
} catch (Exception e) {
String erroMsg = "Error occurred on reading relatioships for id: " + projectID;
LOG.error(erroMsg, e);
}
// TODO LOAD AND APPLT TEMPLATING OF KIND
for (int i = 0; i < 5; i++) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", "UCD"+i+",ID"+i);
jsonObject.put("content",
"title moooooooooooooolto lungoooooooooooooooooooooooooooooooooooooooooooooooooo" + i);
jsonObject.put("start", "201" + i + "-04-1");
jsonObject.put("end", "201" + i + "-09-1");
if (i < 3)
jsonObject.put("image_url",
"https://data-pre.d4science.org/shub/E_ck5hN0hBcGljR3oySm5KOWJxOUMyRkRaWkZ4WnhmWXJjWVlLeWxGcW9FMWQraitOWStmQXREQklNUlMydzNFTw==");
listJSON.add(jsonObject.toString());
}
return listJSON;
} catch (Exception e) {
String erroMsg = "Error occurred on reading relatioships for id: " + projectID;
LOG.error(erroMsg, e);
throw new Exception(erroMsg);
}
}
}