package nl.sogeti.android.gpstracker.actions.tasks; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.net.Uri; import android.os.AsyncTask; import android.util.Log; import nl.sogeti.android.gpstracker.actions.utils.ProgressListener; import nl.sogeti.android.gpstracker.db.DatabaseHelper; import nl.sogeti.android.gpstracker.db.GPStracking; import nl.sogeti.android.gpstracker.util.ByteProgressAdmin; import nl.sogeti.android.gpstracker.util.ProgressFilterInputStream; import org.apache.ogt.http.HttpResponse; import org.apache.ogt.http.client.methods.HttpGet; import org.apache.ogt.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.*; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.CancellationException; /** * Created by IntelliJ IDEA. * User: F8Full * Date: 12-02-29 * Time: 15:56 * This parser is used to import Velov stations into the database */ public class StationsJSONParser extends AsyncTask<String, Void, Uri> //Parameters are input/output types, GpxParser takes an URI for the file reference, //whereas I'll have a collection of URLS { private static final String URL = "http://www.velov.grandlyon.com/velovmap/zhp/inc/"; private static final String PREFIX_QUARTIER = "StationsParArrondissement.php?arrondissement="; private static final String [] QUARTIERS = {"69381", "69382", "69383", "69384", "69385", "69386", "69387", "69388", "69389", "69266", "69034", "69256"}; private static final String TAG = "F8F.StationsJSONParser"; protected String mErrorDialogMessage; protected Exception mErrorDialogException; protected Context mContext; private ContentResolver mContentResolver; private ProgressListener mProgressListener; protected StationsJSONParserProgressAdmin mStationsJSONParserProgressAdmin; //TODO: manage database through the conventional way with versioning and stuff private DatabaseHelper mDbHelper; public StationsJSONParser(Context context, ProgressListener progressListener) { mContext = context; mProgressListener = progressListener; mDbHelper = new DatabaseHelper(mContext); mContentResolver = mContext.getContentResolver(); mStationsJSONParserProgressAdmin = new StationsJSONParserProgressAdmin(); } protected ArrayList<InputStream> getAllJSONStreams() throws Exception //InputStream will hopefully contains as many members as there are boroughs, though for //now I'll let silent fail go on (having only partial data). I will fail if now stream could be reached //TODO: Add warning in case of incomplete data availability { //Vector JSONPerBorough = new Vector(); //SequenceInputStream toReturn = null; ArrayList<InputStream> toReturn = new ArrayList<InputStream>(); long totalLength = 0; for (int i=0; i<QUARTIERS.length; ++i) { DefaultHttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(URL + PREFIX_QUARTIER + QUARTIERS[i]); HttpResponse response = client.execute(request); toReturn.add(response.getEntity().getContent()); totalLength += response.getEntity().getContentLength(); } if(toReturn.size() <= 0) { throw new Exception(); } mStationsJSONParserProgressAdmin.setContentLength(totalLength); return toReturn; } /*public Uri importStationsFromJSONURLs(String[] importJSONURLs) { } */ // This is way too specific //TODO : have this in some generic way if the compatibility list is to expand (which I highly doubt) public Uri importStationsFromVelovJSONURLs() { Uri result = null; ArrayList<InputStream> JSONInputStreamsList= null; try { JSONInputStreamsList = getAllJSONStreams(); } catch (Exception e) { handleError(e, "JSON opening exception"); } if(JSONInputStreamsList.size() > 0) { mDbHelper.dropStationsTable(); mDbHelper.createStationsTable(); } Iterator<InputStream> iterator = JSONInputStreamsList.iterator(); //THIS WILL LOOP THROUGH ALL INPUSTREAM RETURNED FROM THE OTHER FUNCTION, while(iterator.hasNext()) { ImportStations(iterator.next()); } return result; } public Uri ImportStations(InputStream JSONInputStream) { //{"markers":[{"numStation":"1001","nomStation":"1001 - Terreaux \/ Terme","x":"45.76765100000000","y":"4.832158000000000", // "infoStation":"Angle rue d'Alg\u00e9rie"},{"numStation":"1002","nomStation":"1002 - Op\u00e9ra","x":"45.76751200000000", // "y":"4.836279000000000","infoStation":"Angle rue Serlin - Angle place de la com\u00e9die"},...]} Uri result = null; try { ProgressFilterInputStream pfis = new ProgressFilterInputStream(JSONInputStream, mStationsJSONParserProgressAdmin); BufferedInputStream bis = new BufferedInputStream(pfis); InputStreamReader ISReader= new InputStreamReader(bis); BufferedReader reader = new BufferedReader(ISReader); String json = reader.readLine(); JSONObject markersObject = new JSONObject(json); JSONArray stations = markersObject.getJSONArray("markers"); ContentValues stationContent = new ContentValues(); for(int i=0; i<stations.length(); ++i) { JSONObject cur = stations.getJSONObject(i); stationContent.put(GPStracking.Stations._ID, cur.getInt("numStation")); stationContent.put(GPStracking.Stations.NAME, cur.getString("nomStation")); stationContent.put(GPStracking.Stations.LATITUDE, cur.getDouble("x")); stationContent.put(GPStracking.Stations.LONGITUDE, cur.getDouble("y")); mContentResolver.insert(GPStracking.Stations.CONTENT_URI, stationContent); stationContent.clear(); } } catch (IOException e) { handleError(e, "error while building JSONArray"); } catch (JSONException e) { handleError(e, "error while building JSONArray"); } return result; } /** * * @param dialogException * @param dialogErrorMessage */ protected void handleError(Exception dialogException, String dialogErrorMessage) { Log.e(TAG, "Unable to save ", dialogException); mErrorDialogException = dialogException; mErrorDialogMessage = dialogErrorMessage; cancel(false); throw new CancellationException(dialogErrorMessage); } @Override protected Uri doInBackground(String... params) { //String url = params[0]; return importStationsFromVelovJSONURLs(); } @Override protected void onPreExecute() { mProgressListener.started(); } @Override protected void onProgressUpdate(Void... values) { mProgressListener.setProgress(mStationsJSONParserProgressAdmin.getProgress()); } @Override protected void onPostExecute(Uri result) { mProgressListener.finished(result); } @Override protected void onCancelled() { //mProgressListener.showError(mContext.getString(R.string.taskerror_gpx_import), mErrorDialogMessage, mErrorDialogException); mProgressListener.showError("oups", mErrorDialogMessage, mErrorDialogException); } public class StationsJSONParserProgressAdmin extends ByteProgressAdmin { public void addBytesProgress(int addedBytes) { super.addBytesProgress(addedBytes); considerPublishProgress(); } @Override public void considerPublishProgress() { if(mustPublishProgress()) { publishProgress(); } } } }