package de.ifgi.lod4wfs.factory; import it.cutruzzula.lwkt.WKTParser; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.LukeRequest; import org.apache.solr.client.solrj.response.LukeResponse; import org.apache.solr.client.solrj.response.LukeResponse.FieldInfo; import org.apache.solr.common.SolrDocumentList; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import de.ifgi.lod4wfs.core.GlobalSettings; import de.ifgi.lod4wfs.core.SOLRRecord; import de.ifgi.lod4wfs.core.Utils; import de.ifgi.lod4wfs.core.WFSFeature; import de.ifgi.lod4wfs.infrastructure.SOLRConnector; /** * @author Jim Jones */ public class FactorySOLRFeatures { private static Logger logger = Logger.getLogger("SOLRFeatures-Factory"); public ArrayList<WFSFeature> listSOLRFeatures() { File[] files = new File(GlobalSettings.getFeatureDirectory()).listFiles(); logger.info("Listing features from the direcoty " + System.getProperty("user.dir") + File.separator + GlobalSettings.getFeatureDirectory() + " ..."); ArrayList<WFSFeature> result = new ArrayList<WFSFeature>(); for (File file : files) { if(file.getName().endsWith(".solr")){ WFSFeature feature = new WFSFeature(); feature = this.getSOLRFeature(file.getName()); if(feature != null){ result.add(feature); } } } logger.info("Total SOLR Features: " + result.size()); return result; } public WFSFeature getSOLRFeature(String fileName){ WFSFeature feature = new WFSFeature(); try { FileReader fileReader = new FileReader(GlobalSettings.getFeatureDirectory() + fileName); JsonParser jParser = new JsonParser(); JsonObject jObject = (JsonObject) jParser.parse(fileReader); feature.setFeatureAbstract(jObject.get("abstract").getAsString()); feature.setTitle(jObject.get("title").getAsString()); feature.setName(jObject.get("name").getAsString()); feature.setKeywords(jObject.get("keywords").getAsString()); feature.setGeometryVariable(jObject.get("geometryVariable").getAsString()); feature.setEndpoint(jObject.get("endpoint").getAsString()); feature.setSOLRSorting(jObject.get("order").getAsString()); feature.setLimit(jObject.get("limit").getAsInt()); feature.setFields(jObject.get("fields").getAsString()); feature.setSOLRFilter(jObject.get("filter").getAsString()); JsonElement elem = jObject.get("spatialFilter"); feature.setSOLRSpatialConstraint(elem.getAsJsonObject().get("spatialConstraint").getAsString()); feature.setSOLRGeometryField(elem.getAsJsonObject().get("geometryField").getAsString()); feature.setLowerCorner(GlobalSettings.getDefaultLowerCorner()); feature.setUpperCorner(GlobalSettings.getDefaultUpperCorner()); if(jObject.get("crs").getAsString().equals("")){ feature.setCRS(GlobalSettings.getDefaultCRS()); } else { feature.setCRS(jObject.get("crs").getAsString()); } feature.setFileName(fileName); feature.setAsSOLRFeature(true); } catch (FileNotFoundException e) { e.printStackTrace(); } return feature; } private static boolean isGeometryValid(String wkt){ boolean result = true; try { WKTParser.parseToGML2(wkt); } catch(Exception e) { result = false; } return result; } public static String getGeometryType(String wkt){ String result = new String(); //Removing Spatial Reference System if(wkt.contains("<") && wkt.contains(">")){ wkt = wkt.substring(wkt.indexOf(">") + 1, wkt.length()); } //Removing literal type. if(wkt.contains("^^")){ wkt = wkt.substring(0, wkt.indexOf("^^")); } if(isGeometryValid(wkt.toUpperCase())){ try { result = WKTParser.parse(wkt.toUpperCase()).getType().toString(); } catch (Exception e) { e.printStackTrace(); } } else { result = "INVALID"; } return result; } /** * @param WFS feature * @return Lists all predicates (properties) related to a given feature. */ public ArrayList<SOLRRecord> getSOLRFeatureFields(WFSFeature feature){ logger.info("Listing available fields for the SOLR-Based feature [" + feature.getName() + "] ..."); ArrayList<SOLRRecord> result = new ArrayList<SOLRRecord>(); HttpSolrServer solr = new HttpSolrServer(feature.getEndpoint()); try { /** * "*" means all fields. */ if (feature.getFields().equals("*")){ LukeRequest lukeRequest = new LukeRequest(); lukeRequest.setNumTerms(1); LukeResponse lukeResponse; lukeResponse = lukeRequest.process(solr); List<FieldInfo> sorted = new ArrayList<FieldInfo>(lukeResponse.getFieldInfo().values()); for (FieldInfo infoEntry : sorted) { SOLRRecord record = new SOLRRecord(); record.setName(infoEntry.getName()); if(infoEntry.getName().equals(feature.getGeometryVariable())){ //TODO: Hard-coded geometry type! // record.setType(this.getSOLRGeometryType(feature)); record.setType("gml:MultiPolygonPropertyType"); } else { if(infoEntry.getType().equals("long")){ record.setType(GlobalSettings.getDefaultLongType()); } else if(infoEntry.getType().equals("text_general")){ record.setType(GlobalSettings.getDefaultStringType()); } else if(infoEntry.getType().equals("location_rpt")){ record.setType(GlobalSettings.getDefaultStringType()); } else if(infoEntry.getType().equals("string")){ record.setType(GlobalSettings.getDefaultStringType()); } else if(infoEntry.getType().equals("date")){ record.setType(GlobalSettings.getDefaultStringType()); } else if(infoEntry.getType().equals("float")){ record.setType(GlobalSettings.getDefaultFloatType()); } else if(infoEntry.getType().equals("int")){ record.setType(GlobalSettings.getDefaultIntegerType()); } else { record.setType(GlobalSettings.getDefaultStringType()); logger.warn("Unpexpected data type for SOLR Feature [" + feature.getName() + "] The field \"" + infoEntry.getName() + "\" has the data type \"" + infoEntry.getType() + "\""); } } result.add(record); } } else { String[] fields = new String[feature.getFields().split(",").length]; fields = feature.getFields().split(","); SOLRRecord geometryField = new SOLRRecord(); geometryField.setType(this.getSOLRGeometryType(feature)); geometryField.setName(feature.getSOLRGeometryField()); result.add(geometryField); for (int i = 0; i < fields.length; i++) { SOLRRecord record = new SOLRRecord(); record.setName(fields[i].trim()); record.setType(GlobalSettings.getDefaultStringType()); result.add(record); } } } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } public String getSOLRGeometryType(WFSFeature feature){ logger.info("Getting geometry type for the SOLR-Based feature [" + feature.getName() + "] ..."); String result = new String(); int tmpLimit = feature.getLimit(); feature.setLimit(1); SOLRConnector solrConnector = new SOLRConnector(); SolrDocumentList rs = solrConnector.executeQuery(feature); for (int i = 0; i < rs.size(); i++) { result = Utils.getGeometryType(rs.get(i).getFieldValue(feature.getGeometryVariable()).toString()); } feature.setLimit(tmpLimit); return result; } }