package org.gcube.portlets.user.geoportaldataviewer.server; import static org.gcube.resources.discovery.icclient.ICFactory.client; import java.io.StringReader; import java.net.URLDecoder; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.gcube.common.resources.gcore.utils.XPathHelper; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaDataViewerProfile; import org.gcube.portlets.user.geoportaldataviewer.shared.gis.LayerItem; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.Query; import org.gcube.resources.discovery.client.queries.impl.QueryBox; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * The Class GeoNaViewerProfileReader. * * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * * Nov 12, 2020 */ public class GeoNaDataViewerProfileReader { private static final String RESOURCE_PROFILE_BODY = "/Resource/Profile/Body"; /** * */ public static final String SECONDARY_TYPE = "ApplicationProfile"; public static final String WORKSPACE_EXPLORER_APP_NAME = "GeoNa-Viewer-Profile"; private Logger logger = LoggerFactory.getLogger(GeoNaDataViewerProfileReader.class); private String secondaryType; private String scope; private String appID; /** * Instantiates a new application profile reader. * * @param appID the app id */ public GeoNaDataViewerProfileReader(String appID) { this.appID = appID; this.secondaryType = SECONDARY_TYPE; this.scope = ScopeProvider.instance.get(); } /** * Read profile from infrastrucure. * * @return the map */ public GeoNaDataViewerProfile readProfileFromInfrastrucure() throws Exception { String queryString = getGcubeGenericQueryString(secondaryType, appID); logger.info("Scope "+scope+", trying to perform query: "+queryString); try { if (scope == null) throw new Exception("Scope is null, set scope into ScopeProvider"); GeoNaDataViewerProfile profile = new GeoNaDataViewerProfile(); logger.info("Trying to fetch ApplicationProfile in the scope: " + scope + ", SecondaryType: " + secondaryType + ", AppId: " + appID); Query q = new QueryBox(queryString); DiscoveryClient client = client(); List appProfile = client.submit(q); if (appProfile == null || appProfile.size() == 0) throw new ApplicationProfileNotFoundException("ApplicationProfile with SecondaryType: " + secondaryType + ", AppId: " + appID + " is not registered in the scope: " + scope); else { String elem = appProfile.get(0); DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = docBuilder.parse(new InputSource(new StringReader(elem))); XPathHelper helper = new XPathHelper(doc.getDocumentElement()); List currValue = null; String xPathExp = RESOURCE_PROFILE_BODY+"/RestrictedPortletURL/text()"; currValue = helper.evaluate(xPathExp); if (currValue != null && currValue.size() > 0) { profile.setRestrictedPortletURL(currValue.get(0)); }else throw new Exception("I'm not able to read the path: "+xPathExp); xPathExp = RESOURCE_PROFILE_BODY+"/OpenPortletURL/text()"; currValue = helper.evaluate(xPathExp); if (currValue != null && currValue.size() > 0) { profile.setOpenPortletURL(currValue.get(0)); }else throw new Exception("I'm not able to read the path: "+xPathExp); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList nodeList = (NodeList) xPath.compile("/Resource/Profile/Body/AvailableLayers/Layer") .evaluate(doc, XPathConstants.NODESET); Map mapLayers = new HashMap(nodeList.getLength()); for (int i = 0; i < nodeList.getLength(); i++) { Node layerNode = nodeList.item(i); if (layerNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) layerNode; String layerType = eElement.getElementsByTagName("Type").item(0).getTextContent(); String wmsLink = eElement.getElementsByTagName("WMSLink").item(0).getTextContent(); String decodedURL = URLDecoder.decode(wmsLink, "UTF-8"); LayerItem layer = new LayerItem(); layer.setWmsLink(decodedURL); mapLayers.put(layerType.toLowerCase(), layer); } } profile.setMapLayers(mapLayers); logger.info("returning: "+profile); return profile; } } catch (Exception e) { logger.error("Error while trying to read the " + SECONDARY_TYPE + " with SecondaryType " + WORKSPACE_EXPLORER_APP_NAME + " from scope " + scope, e); return null; } finally { } } /** * Gets the gcube generic query string. * * @param secondaryType the secondary type * @param appId the app id * @return the gcube generic query string */ public static String getGcubeGenericQueryString(String secondaryType, String appId) { return "for $profile in collection('/db/Profiles/GenericResource')//Resource " + "where $profile/Profile/SecondaryType/string() eq '" + secondaryType + "' and $profile/Profile/Body/AppId/string() " + " eq '" + appId + "'" + "return $profile"; } /** * Gets the secondary type. * * @return the secondary type */ public String getSecondaryType() { return secondaryType; } /** * Gets the scope. * * @return the scope */ public String getScope() { return scope; } @Override public String toString() { return "GeoNaViewerProfileReader [secondaryType=" + secondaryType + ", scope=" + scope + ", appID=" + appID + "]"; } /* public static void main(String[] args) throws Exception { ScopeProvider.instance.set("/gcube/devNext/NextNext"); GeoNaDataViewerProfileReader gdvp = new GeoNaDataViewerProfileReader("geoportal-data-viewer-app"); GeoNaDataViewerProfile profile = gdvp.readProfileFromInfrastrucure(); System.out.println(profile.getRestrictedPortletURL()); System.out.println(profile.getOpenPortletURL()); if(profile.getMapLayers()!=null) { for (String type : profile.getMapLayers().keySet()) { System.out.println("key: "+type+", value: "+profile.getMapLayers().get(type)); } } }*/ }