package it.geosolutions.android.map.wfs; import it.geosolutions.android.map.BuildConfig; import it.geosolutions.android.map.wfs.geojson.GeoJson; import it.geosolutions.android.map.wfs.geojson.feature.Feature; import it.geosolutions.android.map.wfs.geojson.feature.FeatureCollection; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import android.net.Uri; import android.net.Uri.Builder; import android.util.Base64; import android.util.Log; import com.google.gson.JsonSyntaxException; /** * This is a Client for a WFS Service * @author Lorenzo Natali (lorenzo.natali at geo-solutions.it) * */ public class WFSGeoJsonClient { private String url; private String username; private String password; public Integer totalCount; public String getUrl() { return url; } /** * Set the WFS URL * @param url */ public void setUrl(String url) { this.url = url; } /** * (Basic authentication) * @return username */ public String getUsername() { return username; } /** * Set username for Basic Authentication * @param username */ public void setUsername(String username) { this.username = username; } /** * get password * @return the password */ public String getPassword() { return password; } /** * Set password for Basic Authentication * @param password */ public void setPassword(String password) { this.password = password; } /** * Get Feature with start and limit * @param typeName the name of the FeatureType * @param baseParams the params * @param start displacement from the first feature (needs sorting) * @param limit limit the number of features) * @return */ public List<Feature> getFeature(String typeName,Map<String,String> baseParams, Integer start,Integer limit) { HttpClient httpclient = new DefaultHttpClient(); //create the URI of the request URI uri; try { Builder ub = new Uri.Builder(); //recreate the uri String[] parts = url.split("://"); if(parts.length > 1){ //Set schema ub.scheme(parts[0]); //separate query string parts = parts[1].split("\\?"); //separate path parameters String[] part1 = parts[0].split("/"); //set authority ub.authority(part1[0]); //append path if(part1.length >1){ for(int i=1; i < part1.length;i++){ ub.appendPath(part1[i]); } } //append query parameters if(parts.length > 1){ String queryString = parts[1]; //separate parameters String[] params = queryString.split("&"); for(int i=0; i < params.length;i++){ //separate key and values String[] pel = params[i].split("="); //append if anything ok if(pel.length>1){ ub.appendQueryParameter(pel[0], pel[1]); } } } }else{ throw new URISyntaxException(url,"missing schema or domain"); } ub.appendQueryParameter("request", "GetFeature"); ub.appendQueryParameter("typeName", typeName); //TODO params if(baseParams == null){ baseParams = new HashMap<String,String>(); } //?service=WFS&version=1.0.0&request=GetFeature&typeName=geosolutions:cities&maxFeatures=50&outputFormat=json" //Add default parameters; baseParams.put("service", "WFS"); baseParams.put("version", "1.0.0"); baseParams.put("request", "GetFeature"); baseParams.put("outputFormat", "json"); for(String par : baseParams.keySet()){ ub.appendQueryParameter(par, baseParams.get(par)); } if(limit !=null){ ub.appendQueryParameter("maxfeatures",limit.toString()); if(start != null){//TODO, need a sort criteria!!! ub.appendQueryParameter("startindex",start.toString()); } } Uri ur = ub.build(); uri = new URI(ur.toString()); Log.d("WFS-Geojson","URL:" +uri ); } catch (URISyntaxException e1) { Log.w("WFS-Geojson", "URL not vaild for the request"); return new ArrayList<Feature>(); } Log.d("WFS","request_url:"+uri.toString()); HttpGet get = new HttpGet(uri); if (url == null) { if(BuildConfig.DEBUG){ Log.w("WFS-Geojson", "URL Not Present. Unable to submit the request"); } return new ArrayList<Feature>(); } get.addHeader("Accept", "application/json"); if(username!= null && password!= null){ get.addHeader(new BasicHeader("Authorization", getB64Auth(username, password))); } HttpResponse response; // TODO support pagination, filtering String responseText = null; try { response = httpclient.execute(get); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { // parse response. responseText = EntityUtils.toString(resEntity); // Log.d("WFS-Geojson", "remote service response:"); // Log.d("WFS-Geojson", responseText); GeoJson gson = new GeoJson(); FeatureCollection c = gson.fromJson(responseText, FeatureCollection.class); if(c!= null) { if(c.totalFeatures !=null){ totalCount=c.totalFeatures; } //is a count of the features return c.features; } } } catch (ClientProtocolException e) { // TODO Auto-generated catch block Log.e("WFS-Geojson", "HTTP Protocol error"); return null; } catch (IOException e) { // TODO Auto-generated catch block Log.e("WFS-Geojson", "IOException during HTTP request"); return null; } catch (IllegalArgumentException e){ Log.e("WFS-Geojson","Unable to parse the response:"+responseText); Log.e("WFS-Geojson","Error:"+e.getMessage()); return null; }catch (JsonSyntaxException e){ Log.e("WFS-Geojson","Unable to parse the response:"+responseText); Log.e("WFS-Geojson","Error:"+e.getMessage()); return null; } return new ArrayList<Feature>(); } public boolean test() { HttpClient httpclient = new DefaultHttpClient(); HttpGet get = new HttpGet(url); get.addHeader("Accept", "application/json"); HttpResponse response; // TODO support pagination, filtering try { response = httpclient.execute(get); HttpEntity resEntity = response.getEntity(); String responseText; if (resEntity != null) { // parse response. responseText = EntityUtils.toString(resEntity); Log.d("GeoStore", "remote service response:"); //Workaround for html page if(responseText.contains("RESTful")){ return true; } } }catch (Exception e) { Log.w("GeoStore Client","the test url returned an exception"); } return false; } /** * Generates a string suitable as BasicAuth header value * @param login * @param pass * @return */ public static String getB64Auth( String login, String pass ) { String source = login + ":" + pass; String ret = "Basic " + Base64.encodeToString(source.getBytes(), Base64.URL_SAFE | Base64.NO_WRAP); return ret; } }