/*
* Licensed to Prodevelop SL under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The Prodevelop SL licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* For more information, contact:
*
* Prodevelop, S.L.
* Pza. Don Juan de Villarrasa, 14 - 5
* 46001 Valencia
* Spain
*
* +34 963 510 612
* +34 963 510 968
* prode@prodevelop.es
* http://www.prodevelop.es
*
* @author Alberto Romeu Carrasco http://www.albertoromeu.com
*/
package es.alrocar.poiproxy.proxy;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import es.alrocar.jpe.parser.JPEParser;
import es.alrocar.jpe.parser.JPEParserManager;
import es.alrocar.jpe.parser.csv.CSVParser;
import es.alrocar.jpe.parser.exceptions.NoParserRegisteredException;
import es.alrocar.jpe.parser.json.JSONJPEParser;
import es.alrocar.jpe.parser.kml.KMLParser;
import es.alrocar.jpe.parser.xml.XMLJPEParser;
import es.alrocar.jpe.writer.GeoJSONWriter;
import es.alrocar.poiproxy.configuration.AuthTypeEnum;
import es.alrocar.poiproxy.configuration.DescribeService;
import es.alrocar.poiproxy.configuration.DescribeServices;
import es.alrocar.poiproxy.configuration.Param;
import es.alrocar.poiproxy.configuration.ServiceConfigurationManager;
import es.alrocar.poiproxy.configuration.ServiceParams;
import es.alrocar.poiproxy.exceptions.POIProxyException;
import es.alrocar.poiproxy.geotools.GeotoolsUtils;
import es.alrocar.poiproxy.proxy.event.POIProxyEvent;
import es.alrocar.poiproxy.proxy.event.POIProxyEventEnum;
import es.alrocar.poiproxy.proxy.utiles.Calculator;
import es.alrocar.poiproxy.request.RequestService;
import es.alrocar.poiproxy.request.RequestServices;
import es.alrocar.poiproxy.request.SimpleHttpRequestService;
import es.alrocar.utils.CompressionEnum;
import es.alrocar.utils.Downloader;
import es.alrocar.utils.PropertyLocator;
import es.alrocar.utils.Unzip;
import es.prodevelop.geodetic.utils.conversion.ConversionCoords;
import es.prodevelop.gvsig.mini.geom.Extent;
import es.prodevelop.gvsig.mini.geom.impl.jts.JTSFeature;
import es.prodevelop.gvsig.mini.projection.TileConversor;
import es.prodevelop.gvsig.mobile.fmap.proj.CRSFactory;
/**
* The main entry point of the library. This class has methods to make a request
* to a service, parse the response and return the GeoJSON result
*
* @author albertoromeu
*
*/
public class POIProxy {
private static final String MERCATOR_SRS = "EPSG:900913";
private static final String GEODETIC_SRS = "EPSG:4326";
private final static Logger logger = Logger.getLogger(POIProxy.class);
public static String CACHE_DIR = "/var/lib/sp/cache";
private static POIProxy proxy;
private ServiceConfigurationManager serviceManager;
private RequestServices requestServices;
public final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private List<POIProxyListener> listeners = new ArrayList<POIProxyListener>();
private CacheListener cache;
public static POIProxy asSingleton() {
if (proxy == null) {
proxy = new POIProxy();
proxy.initialize();
}
return proxy;
}
/**
* Instantiates the {@link ServiceConfigurationManager} that loads the
* services available at
* {@link ServiceConfigurationManager#CONFIGURATION_DIR}
*
* Registers a {@link JSONJPEParser} and a {@link XMLJPEParser} to allow
* parsing either json or xml depending on the format response of the
* registered services
*
* And finally instantiates a {@link GeoJSONWriter} that will return the
* GeoJSON document
*/
public void initialize() {
// Registra todos los servicios disponibles
serviceManager = new ServiceConfigurationManager();
registerRequestServices();
JPEParserManager.getInstance().registerJPEParser(new JSONJPEParser());
JPEParserManager.getInstance().registerJPEParser(new XMLJPEParser());
JPEParserManager.getInstance().registerJPEParser(new CSVParser());
JPEParserManager.getInstance().registerJPEParser(new KMLParser());
}
protected void registerRequestServices() {
requestServices = RequestServices.getInstance();
for (AuthTypeEnum authType : AuthTypeEnum.values()) {
if (authType._downloader != null) {
try {
requestServices.addRequestService(authType, authType._downloader.newInstance());
} catch (InstantiationException e) {
logger.error(e.getMessage(), e);
} catch (IllegalAccessException e) {
logger.error(e.getMessage(), e);
}
} else {
requestServices.addRequestService(authType, new SimpleHttpRequestService());
}
}
}
/**
* Returns a JSON containing the describe service document of each service
* registered into the library
*
* @return
* @throws IOException
* @throws JsonMappingException
* @throws JsonGenerationException
*/
public String getAvailableServices() throws JsonGenerationException, JsonMappingException, IOException {
DescribeServices services = serviceManager.getAvailableServices();
return services.asJSON();
}
/**
* This method is used to get the pois from a service and return a GeoJSON
* document with the data retrieved given a Z/X/Y tile.
*
* @param id
* The id of the service
* @param z
* The zoom level
* @param x
* The x tile
* @param y
* The y tile
* @return The GeoJSON response from the original service response
*/
public String getPOIs(String id, int z, int x, int y, List<Param> optionalParams) throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
Extent e1 = TileConversor.tileOSMMercatorBounds(x, y, z);
double[] minXY = ConversionCoords.reproject(e1.getMinX(), e1.getMinY(), CRSFactory.getCRS(MERCATOR_SRS),
CRSFactory.getCRS(GEODETIC_SRS));
double[] maxXY = ConversionCoords.reproject(e1.getMaxX(), e1.getMaxY(), CRSFactory.getCRS(MERCATOR_SRS),
CRSFactory.getCRS(GEODETIC_SRS));
POIProxyEvent beforeEvent = new POIProxyEvent(POIProxyEventEnum.BeforeBrowseZXY, describeService, e1, z, y, x,
null, null, null, null, null, null);
notifyListenersBeforeRequest(beforeEvent);
String geoJSON = getCacheData(beforeEvent);
boolean fromCache = true;
if (geoJSON == null) {
fromCache = false;
geoJSON = getResponseAsGeoJSON(id, optionalParams, describeService, minXY[0], minXY[1], maxXY[0], maxXY[1],
0, 0, beforeEvent);
}
POIProxyEvent afterEvent = new POIProxyEvent(POIProxyEventEnum.AfterBrowseZXY, describeService, e1, z, y, x,
null, null, null, null, geoJSON, null);
if (!fromCache) {
storeData(afterEvent);
}
notifyListenersAfterParse(afterEvent);
return geoJSON;
}
private void storeData(POIProxyEvent afterEvent) {
if (this.cache != null) {
this.cache.write(afterEvent);
}
}
private String getCacheData(POIProxyEvent beforeEvent) {
String result = null;
if (this.cache != null) {
result = this.cache.read(beforeEvent);
}
return result;
}
/**
* This method is used to get the pois from a service and return a list of
* {@link JTSFeature} document with the data retrieved given a Z/X/Y tile.
*
* @param id
* The id of the service
* @param z
* The zoom level
* @param x
* The x tile
* @param y
* The y tile
* @return a list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeatures(String id, int z, int x, int y, List<Param> optionalParams)
throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
Extent e1 = TileConversor.tileOSMMercatorBounds(x, y, z);
double[] minXY = ConversionCoords.reproject(e1.getMinX(), e1.getMinY(), CRSFactory.getCRS(MERCATOR_SRS),
CRSFactory.getCRS(GEODETIC_SRS));
double[] maxXY = ConversionCoords.reproject(e1.getMaxX(), e1.getMaxY(), CRSFactory.getCRS(MERCATOR_SRS),
CRSFactory.getCRS(GEODETIC_SRS));
return getFeatures(id, optionalParams, describeService, minXY[0], minXY[1], maxXY[0], maxXY[1], 0, 0);
}
/**
* This method is used to get the pois from a category and return a list of
* {@link JTSFeature} document with the data retrieved given a Z/X/Y tile.
*
* @param id
* The category to request
* @see #getAvailableCategories()
* @param z
* The zoom level
* @param x
* The x tile
* @param y
* The y tile
* @return a list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeaturesByCategory(String category, int z, int x, int y, List<Param> optionalParams)
throws Exception {
List<String> ids = serviceManager.getAvailableServices().getServicesIDByCategory(category);
ArrayList<JTSFeature> features = new ArrayList<JTSFeature>();
for (String id : ids) {
try {
features.addAll(this.getFeatures(id, z, x, y, optionalParams));
} catch (Exception e) {
logger.error("POIProxy", e);
}
}
return features;
}
/**
* Calls the
* {@link ServiceConfigurationManager#getServiceConfiguration(String)}
*
* @param id
* The id of the service
* @return The {@link DescribeService}
*/
public DescribeService getServiceFromID(String id) {
return serviceManager.getServiceConfiguration(id);
}
/**
* This method is used to get the pois from a service and return a GeoJSON
* document with the data retrieved given a longitude, latitude and a radius
* in meters.
*
* @param id
* The id of the service
* @param lon
* The longitude
* @param lat
* The latitude
* @param distanceInMeters
* The distance in meters from the lon, lat
* @return The GeoJSON response from the original service response
*/
public String getPOIs(String id, double lon, double lat, double distanceInMeters, List<Param> optionalParams)
throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
double[] bbox = Calculator.boundingCoordinates(lon, lat, distanceInMeters);
POIProxyEvent beforeEvent = new POIProxyEvent(POIProxyEventEnum.BeforeBrowseLonLat, describeService,
new Extent(bbox[0], bbox[1], bbox[2], bbox[3]), null, null, null, lon, lat, distanceInMeters, null,
null, null);
notifyListenersBeforeRequest(beforeEvent);
String geoJSON = getCacheData(beforeEvent);
boolean fromCache = true;
if (geoJSON == null) {
fromCache = false;
geoJSON = getResponseAsGeoJSON(id, optionalParams, describeService, bbox[0], bbox[1], bbox[2], bbox[3], lon,
lat, beforeEvent);
}
POIProxyEvent afterEvent = new POIProxyEvent(POIProxyEventEnum.AfterBrowseLonLat, describeService,
new Extent(bbox[0], bbox[1], bbox[2], bbox[3]), null, null, null, lon, lat, distanceInMeters, null,
geoJSON, null);
if (!fromCache) {
storeData(afterEvent);
}
notifyListenersBeforeRequest(afterEvent);
return geoJSON;
}
/**
* This method is used to get the pois from a service and return a list of
* {@link JTSFeature} document with the data retrieved given a longitude,
* latitude and a radius in meters.
*
* @param id
* The id of the service
* @param lon
* The longitude
* @param lat
* The latitude
* @param distanceInMeters
* The distance in meters from the lon, lat
* @return A list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeatures(String id, double lon, double lat, double distanceInMeters,
List<Param> optionalParams) throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
double[] bbox = Calculator.boundingCoordinates(lon, lat, distanceInMeters);
return getFeatures(id, optionalParams, describeService, bbox[0], bbox[1], bbox[2], bbox[3], lon, lat);
}
/**
* This method is used to get the pois from a category and return a list of
* {@link JTSFeature} document with the data retrieved given a longitude,
* latitude and a radius in meters.
*
* @param id
* The id of the service
* @param lon
* The longitude
* @param lat
* The latitude
* @param distanceInMeters
* The distance in meters from the lon, lat
* @return A list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeaturesByCategory(String category, double lon, double lat, double distanceInMeters,
List<Param> optionalParams) throws Exception {
List<String> ids = serviceManager.getAvailableServices().getServicesIDByCategory(category);
ArrayList<JTSFeature> features = new ArrayList<JTSFeature>();
for (String id : ids) {
try {
features.addAll(this.getFeatures(id, lon, lat, distanceInMeters, optionalParams));
} catch (Exception e) {
logger.error("POIProxy", e);
}
}
return features;
}
/**
* This method is used to get the pois from a service and return a GeoJSON
* document with the data retrieved given a bounding box corners
*
* @param id
* The id of the service
* @param minX
*
* @param minY
*
* @param maxX
*
* @param maxY
* @return The GeoJSON response from the original service response
*/
public String getPOIs(String id, double minX, double minY, double maxX, double maxY, List<Param> optionalParams)
throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
POIProxyEvent beforeEvent = new POIProxyEvent(POIProxyEventEnum.BeforeBrowseExtent, describeService,
new Extent(minX, minY, maxX, maxY), null, null, null, null, null, null, null, null, null);
notifyListenersBeforeRequest(beforeEvent);
String geoJSON = this.getCacheData(beforeEvent);
boolean fromCache = true;
if (geoJSON == null) {
fromCache = false;
geoJSON = getResponseAsGeoJSON(id, optionalParams, describeService, minX, minY, maxX, maxY, 0, 0,
beforeEvent);
}
POIProxyEvent afterEvent = new POIProxyEvent(POIProxyEventEnum.AfterBrowseExtent, describeService,
new Extent(minX, minY, maxX, maxY), null, null, null, null, null, null, null, geoJSON, null);
if (!fromCache) {
storeData(afterEvent);
}
notifyListenersAfterParse(afterEvent);
return geoJSON;
}
/**
* This method is used to get the pois from a service and return a list of
* {@link JTSFeature} document with the data retrieved given a bounding box
* corners
*
* @param id
* The id of the service
* @param minX
*
* @param minY
*
* @param maxX
*
* @param maxY
* @return A list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeatures(String id, double minX, double minY, double maxX, double maxY,
List<Param> optionalParams) throws Exception {
DescribeService describeService = getDescribeServiceByID(id);
return getFeatures(id, optionalParams, describeService, minX, minY, maxX, maxY, 0, 0);
}
/**
* This method is used to get the pois from a category and return a list of
* {@link JTSFeature} document with the data retrieved given a bounding box
* corners
*
* @param id
* The id of the service
* @param minX
*
* @param minY
*
* @param maxX
*
* @param maxY
* @return A list of {@link JTSFeature}
*/
public ArrayList<JTSFeature> getFeaturesByCategory(String category, double minX, double minY, double maxX,
double maxY, List<Param> optionalParams) throws Exception {
List<String> ids = serviceManager.getAvailableServices().getServicesIDByCategory(category);
ArrayList<JTSFeature> features = new ArrayList<JTSFeature>();
for (String id : ids) {
try {
features.addAll(getFeatures(id, minX, minY, maxX, maxY, optionalParams));
} catch (Exception e) {
logger.error("POIProxy", e);
}
}
return features;
}
/**
* Given a DescribeService and some mandatory parameters, builds a valid
* request for the POI service
*
* @param describeService
* The DescribeService
* @param minX
* @param minY
* @param maxX
* @param maxY
* @param optionalParams
* A list of {@link Param}
* @param lon
* @param lat
* @return The url string to request to
* @throws POIProxyException
*/
public String buildRequest(DescribeService describeService, double minX, double minY, double maxX, double maxY,
List<Param> optionalParams, double lon, double lat) throws POIProxyException {
ServiceParams params = new ServiceParams();
Extent e1 = new Extent(minX, minY, maxX, maxY);
double[] minXY = GeotoolsUtils.transform(GEODETIC_SRS, describeService.getSRS(),
new double[] { e1.getMinX(), e1.getMinY() });
double[] maxXY = GeotoolsUtils.transform(GEODETIC_SRS, describeService.getSRS(),
new double[] { e1.getMaxX(), e1.getMaxY() });
int distanceMeters = this.getDistanceMeters(e1);
e1.setMinX(minXY[0]);
e1.setMinY(minXY[1]);
e1.setMaxX(maxXY[0]);
e1.setMaxY(maxXY[1]);
params.putParam(ServiceParams.MINX, String.valueOf(minXY[0]));
params.putParam(ServiceParams.MINY, String.valueOf(minXY[1]));
params.putParam(ServiceParams.MAXX, String.valueOf(maxXY[0]));
params.putParam(ServiceParams.MAXY, String.valueOf(maxXY[1]));
double longitude = (lon != 0) ? lon : e1.getCenter().getX();
double latitude = (lat != 0) ? lat : e1.getCenter().getY();
params.putParam(ServiceParams.LON, String.valueOf(longitude));
params.putParam(ServiceParams.LAT, String.valueOf(latitude));
params.putParam(ServiceParams.FORMAT, "json");
params.putParam(ServiceParams.DIST, String.valueOf((int) distanceMeters));
params.putParam(ServiceParams.DISTKM, String.valueOf(Double.valueOf(distanceMeters) / 1000));
params.putParam(ServiceParams.KEY, describeService.getApiKey());
if (optionalParams != null) {
String p;
for (Param optParam : optionalParams) {
//NO IDEA HOW CAN THIS BE NULL BUT IT IS HAPPENING
if (optParam == null) {
continue;
}
p = params.getServiceParamFromURLParam(optParam.getType());
if (p == null) {
if (describeService.isEncodeUrl()) {
try {
params.putParam(p, URLEncoder.encode(optParam.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
logger.warn(e);
}
} else {
params.putParam(optParam.getType(), optParam.getValue());
}
} else {
if (describeService.isEncodeUrl()) {
try {
params.putParam(p, URLEncoder.encode(optParam.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
logger.warn(e);
}
} else {
params.putParam(p, optParam.getValue());
}
}
}
}
String url = describeService.getRequestForParam(optionalParams, params);
Set<String> keys = params.getParams().keySet();
Iterator<String> it = keys.iterator();
String key;
while (it.hasNext()) {
key = it.next();
if (describeService.isSpecialParam(key)) {
url = url.replaceAll(key, getValue(params, key, describeService));
}
}
return url;
}
protected String getValue(ServiceParams params, String key, DescribeService describeService)
throws POIProxyException {
if (params.isDate(key)) {
return describeService.encodeParam(getValueForDate(params, key, describeService));
} else {
return describeService.encodeParam(params.getValueForParam(key));
}
}
protected String getValueForDate(ServiceParams params, String key, DescribeService describeService)
throws POIProxyException {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
try {
if (describeService.getDateFormat().compareTo(DescribeService.TIMESTAMP) == 0) {
return sdf.parse(params.getValueForParam(key)).getTime() + "";
} else {
SimpleDateFormat outsdf = new SimpleDateFormat(describeService.getDateFormat());
Date date = sdf.parse(params.getValueForParam(key));
return outsdf.format(date);
}
} catch (ParseException e) {
logger.warn(e);
throw new POIProxyException("Error with dates");
}
}
/**
* Calls
* {@link Downloader#downloadFromUrl(String, es.prodevelop.gvsig.mini.utiles.Cancellable)}
*
* @param url
* The url to request to
* @param service
* The {@link DescribeService} object
* @param id
* The ID of the {@link DescribeService}
* @return The data downloaded
* @throws Exception
*/
public String doRequest(String url, DescribeService service, String id) throws Exception {
RequestService request = requestServices.getRequestService(service.getAuthType());
byte[] data = request.download(url, id, PropertyLocator.getInstance().tempFolder + id + File.separator,
service.getAuth());
System.out.println(url);
if (service.getCompression() != null && service.getCompression().equals(CompressionEnum.ZIP.format)) {
Unzip unzip = new Unzip();
unzip.unzip(PropertyLocator.getInstance().tempFolder + id + File.separator,
PropertyLocator.getInstance().tempFolder + id + File.separator + id, true);
Downloader opener = new Downloader();
return opener.openFile(
PropertyLocator.getInstance().tempFolder + id + File.separator + service.getContentFile());
}
return new String(data, service.getEncoding());
}
/**
* Called after {@link #doRequest(String)} succesfully downlaods the data.
*
* This method gets the {@link JPEParser} implementation given the
* {@link DescribeService#getFormat()} and calls
* {@link JPEParser#parse(String, DescribeService)}
*
* Once the response is parsed succesfully returns the GeoJSON response
*
* @param json
* The json document retrieved from the source service
* @param service
* The {@link DescribeService} used to parse the json
* @return A GeoJSON
* @throws NoParserRegisteredException
*/
public String onResponseReceived(String json, DescribeService service, LocalFilter localFilter,
POIProxyEvent tempEvent) throws NoParserRegisteredException {
final JPEParser jpeParser = JPEParserManager.getInstance().getJPEParser(service.getFormat());
ArrayList<JTSFeature> features = jpeParser.parse(json, service, localFilter);
String geoJSON = jpeParser.getGeoJSON();
POIProxyEventEnum ev = POIProxyEventEnum.FeaturesParsedLonLat;
if (tempEvent.getLat() == null) {
ev = POIProxyEventEnum.FeaturesParsedZXY;
}
POIProxyEvent event = new POIProxyEvent(ev, service, tempEvent.getExtent(), tempEvent.getZ(), tempEvent.getY(),
tempEvent.getX(), tempEvent.getLon(), tempEvent.getLat(), tempEvent.getDistance(), tempEvent.getQuery(),
geoJSON, features);
notifyListenersOnNewFeatures(event);
if (cache != null) {
geoJSON = cache.onFeaturesParsed(event);
}
// Escribir en cache el geoJSON
return geoJSON;
}
private ArrayList<JTSFeature> parseFeatures(String json, DescribeService service, LocalFilter localFilter)
throws NoParserRegisteredException {
final JPEParser jpeParser = JPEParserManager.getInstance().getJPEParser(service.getFormat());
return jpeParser.parse(json, service, localFilter);
}
/**
* Utility method to get the distance from the bottom left corner of the
* bounding box to the upper right corner
*
* @param boundingBox
* The bounding box
* @return The distance in meters
*/
public int getDistanceMeters(Extent boundingBox) {
return new Double(Math.floor(Calculator.latLonDist(boundingBox.getMinX(), boundingBox.getMinY(),
boundingBox.getMaxX(), boundingBox.getMaxY()))).intValue();
}
/**
* Frees this instance of {@link POIProxy}
*/
public void destroy() {
logger.debug("Goodbye POIProxy");
for (POIProxyListener listener : listeners) {
listener.destroy();
}
logger.debug("ZZZzzzzzZZzzZz");
}
/**
* Iterates the {@link DescribeServices} and returns a list of categories
* configured
*
* @return
*/
public List<String> getAvailableCategories() {
DescribeServices services = serviceManager.getAvailableServices();
return services.getCategories();
}
private DescribeService getDescribeServiceByID(String id) throws POIProxyException {
DescribeService describeService = this.getServiceFromID(id);
if (describeService == null) {
throw new POIProxyException(this.getErrorForUnknownService(id));
}
return describeService;
}
/**
* Exception text when a service requested is not registered into the
* library
*
* @param id
* The id of the service not found
* @return The Exception text to show to the user
*/
private String getErrorForUnknownService(String id) {
StringBuffer error = new StringBuffer();
error.append("Services path: " + ServiceConfigurationManager.CONFIGURATION_DIR);
error.append("The service with id: " + id + " is not registered");
error.append("\n Available services are: ");
Set<String> keys = serviceManager.getRegisteredConfigurations().keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
error.append(it.next()).append(" ");
}
return error.toString();
}
private String getResponseAsGeoJSON(String id, List<Param> optionalParams, DescribeService describeService,
double minX, double minY, double maxX, double maxY, double lon, double lat, POIProxyEvent event)
throws Exception, NoParserRegisteredException {
String url = buildRequest(describeService, minX, minY, maxX, maxY, optionalParams, lon, lat);
String file = doRequest(url, describeService, id);
String geoJSON = this.onResponseReceived(file, describeService, describeService.getLocalFilter(optionalParams),
event);
return geoJSON;
}
private ArrayList<JTSFeature> getFeatures(String id, List<Param> optionalParams, DescribeService describeService,
double minX, double minY, double maxX, double maxY, double lon, double lat)
throws Exception, NoParserRegisteredException {
String url = buildRequest(describeService, minX, minY, maxX, maxY, optionalParams, lon, lat);
String file = doRequest(url, describeService, id);
ArrayList<JTSFeature> features = this.parseFeatures(file, describeService,
LocalFilter.fromOptionalParams(optionalParams));
return features;
}
/**
* Interface for registering a new service in POIProxy
*
* @param service
* The {@link DescribeService}
* @param describeService
* The JSON representation of the DescribeService for hot
* registering
* @throws POIProxyException
*/
public void register(DescribeService service, String describeService) throws POIProxyException {
serviceManager.registerServiceConfiguration(service.getId(), describeService, service);
}
/**
* Registers a {@link POIProxyListener}
*
* @param listener
* A {@link POIProxyListener} to get notified on {@link POIProxy}
* events
*/
public void addPOIProxyListener(POIProxyListener listener) {
if (!listeners.contains(listener)) {
this.listeners.add(listener);
}
}
/**
* Removes a registered {@link POIProxyListener}. After removing it, it will
* not receive events anymore
*
* @param listener
* The {@link POIProxyListener}
*/
public void removePOIProxyListener(POIProxyListener listener) {
this.listeners.remove(listener);
}
private boolean notifyListenersBeforeRequest(POIProxyEvent poiProxyEvent) {
boolean result = true;
for (POIProxyListener listener : listeners) {
result = result || listener.beforeRequest(poiProxyEvent);
}
return result;
}
private boolean notifyListenersOnNewFeatures(POIProxyEvent poiProxyEvent) {
boolean result = true;
for (POIProxyListener listener : listeners) {
listener.onNewFeatures(poiProxyEvent);
}
return result;
}
private void notifyListenersAfterParse(POIProxyEvent poiProxyEvent) {
for (POIProxyListener listener : listeners) {
listener.afterParseResponse(poiProxyEvent);
}
}
public void setCacheListener(CacheListener listener) {
this.cache = listener;
}
}