package de.ifgi.lod4wfs.factory; import java.io.IOException; import java.util.ArrayList; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import de.ifgi.lod4wfs.core.GlobalSettings; import de.ifgi.lod4wfs.core.Utils; import de.ifgi.lod4wfs.core.WFSFeature; /** * @author Jim Jones * @tutorial: https://www.overleaf.com/1324048zhbcdw#/3368311/ */ public class FactoryWFS { private static FactoryWFS instance; private FactorySDAFeatures factorySDA; private FactoryFDAFeatures factoryFDA; private FactorySOLRFeatures factorySOLR; private static Model modelFeatures; private static ArrayList<WFSFeature> fdaFeatureList; private static ArrayList<WFSFeature> sdaFeatureList; private static ArrayList<WFSFeature> solrFeatureList; private static Logger logger = Logger.getLogger("WFS-Factory"); public FactoryWFS() { factorySDA = new FactorySDAFeatures(); factoryFDA = new FactoryFDAFeatures(); factorySOLR = new FactorySOLRFeatures(); } public static FactoryWFS getInstance() { if (instance == null) { instance = new FactoryWFS(); } return instance; } public String getCapabilities(String version){ String resultCapabilities = new String(); ArrayList<WFSFeature> features = new ArrayList<WFSFeature>(); fdaFeatureList = null; sdaFeatureList = null; solrFeatureList = null; GlobalSettings.refreshSystemVariables(); if(GlobalSettings.isSolrEnabled()){ solrFeatureList = factorySOLR.listSOLRFeatures(); for (int i = 0; i < solrFeatureList.size(); i++) { features.add(solrFeatureList.get(i)); } } else { logger.warn("SOLR Features support disabled."); } if(GlobalSettings.isFdaEnabled()){ fdaFeatureList = factoryFDA.listFDAFeatures(); for (int i = 0; i < fdaFeatureList.size(); i++) { /** * Checks if the feature is enabled for download. */ if(fdaFeatureList.get(i).isEnabled()){ features.add(fdaFeatureList.get(i)); } else { logger.warn("FDA Feature [" + fdaFeatureList.get(i).getName() + "] disabled. This feature will not appear in the Capabilities Document."); } } } else { logger.warn("FDA Features support disabled."); } if(GlobalSettings.isSdaEnabled()){ sdaFeatureList = factorySDA.listSDAFeatures(); for (int i = 0; i < sdaFeatureList.size(); i++) { features.add(sdaFeatureList.get(i)); } } else { logger.warn("SDA Features support disabled."); } this.generateLayersPrefixes(features); try { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); if (version.equals("1.0.0")) { Document document = documentBuilder.parse("wfs/CapabilitiesDocument_100.xml"); /** * Iterates through the layers' model and creates NameSpaces' entries with the layers prefixes. */ Element requestElement = document.getDocumentElement(); for (Map.Entry<String, String> entry : modelFeatures.getNsPrefixMap().entrySet()) { requestElement.setAttribute("xmlns:" + entry.getKey(), entry.getValue()); } logger.info("Creating Capabilities Document from " + Utils.getCanonicalHostName() + ":" + GlobalSettings.getDefaultPort() + "/" + GlobalSettings.getDefaultServiceName() + "/wfs ..."); XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodeList = (NodeList) xpath.compile("//FeatureTypeList/text()").evaluate(document, XPathConstants.NODESET); /** * Adding LOD features (SDA and FDA) in the Capabilities Document. */ for (int i = 0; i < features.size(); i++) { Element nameElement = document.createElement("Name"); nameElement.appendChild(document.createTextNode(modelFeatures.shortForm(features.get(i).getName()))); Element titleElement = document.createElement("Title"); titleElement.appendChild(document.createTextNode(features.get(i).getTitle())); Element featureAbstractElement = document.createElement("Abstract"); featureAbstractElement.appendChild(document.createTextNode(features.get(i).getFeatureAbstract())); Element keywordsElement = document.createElement("Keywords"); keywordsElement.appendChild(document.createTextNode(features.get(i).getKeywords())); Element crsElement = document.createElement("SRS"); crsElement.appendChild(document.createTextNode(features.get(i).getCRS())); Element bboxElement = document.createElement("LatLongBoundingBox"); bboxElement.setAttribute("maxy", "83.6274"); bboxElement.setAttribute("maxx", "-180"); bboxElement.setAttribute("miny", "-90"); bboxElement.setAttribute("minx", "180"); Element featureElement = document.createElement("FeatureType"); featureElement.appendChild(nameElement); featureElement.appendChild(titleElement); featureElement.appendChild(featureAbstractElement); featureElement.appendChild(keywordsElement); featureElement.appendChild(crsElement); featureElement.appendChild(bboxElement); nodeList.item(1).getParentNode().insertBefore(featureElement, nodeList.item(1)); } resultCapabilities = Utils.printXMLDocument(document); } } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (XPathExpressionException e) { e.printStackTrace(); } resultCapabilities = resultCapabilities.replace("PARAM_PORT", Integer.toString(GlobalSettings.getDefaultPort())); resultCapabilities = resultCapabilities.replace("PARAM_HOST", Utils.getCanonicalHostName()); resultCapabilities = resultCapabilities.replace("PARAM_SERVICE", GlobalSettings.getDefaultServiceName()); return resultCapabilities; } public String describeFeatureType(WFSFeature feature){ String describeFeatureTypeResponse = new String(); if(GlobalSettings.isSolrEnabled()){ if(this.isSOLRFeature(feature)){ describeFeatureTypeResponse = AdapterSOLR4WFS.getInstance().describeFeatureType(feature); } } if(GlobalSettings.isFdaEnabled()){ if(this.isFDAFeature(feature)){ for (int i = 0; i < fdaFeatureList.size(); i++) { if(fdaFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ feature = fdaFeatureList.get(i); } } describeFeatureTypeResponse = AdapterLOD4WFS.getInstance().describeFeatureType(feature); } } if(GlobalSettings.isSdaEnabled()){ if(this.isSDAFeature(feature)){ describeFeatureTypeResponse = AdapterLOD4WFS.getInstance().describeFeatureType(feature); } } return describeFeatureTypeResponse; } public String getFeature(WFSFeature feature){ String getFeatureResponse = new String(); if(GlobalSettings.isSolrEnabled()){ if(this.isSOLRFeature(feature)){ for (int i = 0; i < solrFeatureList.size(); i++) { if(solrFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ feature.setQuery(solrFeatureList.get(i).getQuery()); feature.setGeometryVariable(solrFeatureList.get(i).getGeometryVariable()); feature.setEndpoint(solrFeatureList.get(i).getEndpoint()); } } getFeatureResponse = AdapterSOLR4WFS.getInstance().getFeature(feature); } } if (GlobalSettings.isFdaEnabled()) { if(this.isFDAFeature(feature)){ logger.info("Loading Table of Contents for feature [" + feature.getName() + "]"); for (int i = 0; i < fdaFeatureList.size(); i++) { if(fdaFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ feature.setTableOfContents(fdaFeatureList.get(i).getTableOfContents()); feature.setQuery(fdaFeatureList.get(i).getQuery()); feature.setGeometryVariable(fdaFeatureList.get(i).getGeometryVariable()); feature.setEndpoint(fdaFeatureList.get(i).getEndpoint()); feature.setAsFDAFeature(true); } } getFeatureResponse = AdapterLOD4WFS.getInstance().getFeature(feature); } } if(GlobalSettings.isSdaEnabled()){ if(this.isSDAFeature(feature)){ // feature.setGeometryVariable(sdaFeatureList.get(i).getGeometryVariable()); // feature.setEndpoint(sdaFeatureList.get(i).getEndpoint()); feature.setAsSDAFeature(true); getFeatureResponse = AdapterLOD4WFS.getInstance().getFeature(feature); } } return getFeatureResponse; } //TODO implement a return type for generateLayersPrefixes(). Put a value direct in a variable isn't recommended. private void generateLayersPrefixes(ArrayList<WFSFeature> features){ Pattern pattern = Pattern.compile("[^a-z0-9A-Z_]"); modelFeatures = ModelFactory.createDefaultModel(); for (int i = 0; i < features.size(); i++) { boolean scape = false; int size = features.get(i).getName().length()-1; int position = 0; while ((scape == false) && (size >= 0)) { Matcher matcher = pattern.matcher(Character.toString(features.get(i).getName().charAt(size))); boolean finder = matcher.find(); if (finder == true) { position = size; scape = true; } size--; } if(features.get(i).isSOLRFeature()){ modelFeatures.setNsPrefix(GlobalSettings.getSOLRPrefix(), features.get(i).getName().substring(0, position+1) ); } if (modelFeatures.getNsURIPrefix(features.get(i).getName().substring(0, position + 1)) == null) { if (features.get(i).isFDAFeature()){ modelFeatures.setNsPrefix(GlobalSettings.getFDAPrefix(), features.get(i).getName().substring(0, position+1) ); } else { modelFeatures.setNsPrefix(GlobalSettings.getSDAPrefix() + modelFeatures.getNsPrefixMap().size(), features.get(i).getName().substring(0, position + 1) ); } } } } private boolean isFDAFeature(WFSFeature feature){ boolean result = false; /** * Checks if the selected layer is created via FDA (based on pre-defined SPARQL Query) */ for (int i = 0; i < fdaFeatureList.size(); i++) { if(fdaFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ result = true; } } return result; } private boolean isSDAFeature(WFSFeature feature){ boolean result = false; /** * Checks if the selected layer is created via SDA. */ for (int i = 0; i < sdaFeatureList.size(); i++) { if(sdaFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ result = true; } } return result; } private boolean isSOLRFeature(WFSFeature feature){ boolean result = false; /** * Checks if the selected layer is created via FDA (based on pre-defined SPARQL Query) */ for (int i = 0; i < solrFeatureList.size(); i++) { if(solrFeatureList.get(i).getName().equals(modelFeatures.expandPrefix(feature.getName()))){ result = true; } } return result; } public boolean existsFeature(String featureName){ fdaFeatureList = factoryFDA.listFDAFeatures(); boolean result = false; for (int i = 0; i < fdaFeatureList.size(); i++) { if(fdaFeatureList.get(i).getName().equals(GlobalSettings.getFDAFeaturesNameSpace()+ featureName)){ result = true; } } return result; } public ArrayList<WFSFeature> getLoadedSOLRFeatures(){ return solrFeatureList; } public Model getLoadedModelFeature(){ return modelFeatures; } }