/*------------------------------------------------------------------------------
** Ident: Sogeti Smart Mobile Solutions
** Author: rene
** Copyright: (c) Apr 24, 2011 Sogeti Nederland B.V. All Rights Reserved.
**------------------------------------------------------------------------------
** Sogeti Nederland B.V. | No part of this file may be reproduced
** Distributed Software Engineering | or transmitted in any form or by any
** Lange Dreef 17 | means, electronic or mechanical, for the
** 4131 NJ Vianen | purpose, without the express written
** The Netherlands | permission of the copyright holder.
*------------------------------------------------------------------------------
*
* This file is part of OpenGPSTracker.
*
* OpenGPSTracker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenGPSTracker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenGPSTracker. If not, see <http://www.gnu.org/licenses/>.
*
*/
package nl.sogeti.android.gpstracker.adapter;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;
import java.util.Queue;
import nl.sogeti.android.gpstracker.R;
import nl.sogeti.android.gpstracker.actions.tasks.GpxParser;
import nl.sogeti.android.gpstracker.actions.utils.ProgressListener;
import nl.sogeti.android.gpstracker.adapter.tasks.DownloadBreadcrumbsTrackTask;
import nl.sogeti.android.gpstracker.adapter.tasks.GetBreadcrumbsActivitiesTask;
import nl.sogeti.android.gpstracker.adapter.tasks.GetBreadcrumbsBundlesTask;
import nl.sogeti.android.gpstracker.adapter.tasks.GetBreadcrumbsTracksTask;
import nl.sogeti.android.gpstracker.adapter.tasks.UploadBreadcrumbsTrackTask;
import nl.sogeti.android.gpstracker.oauth.PrepareRequestTokenActivity;
import nl.sogeti.android.gpstracker.util.Constants;
import nl.sogeti.android.gpstracker.util.Pair;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import org.apache.ogt.http.conn.ClientConnectionManager;
import org.apache.ogt.http.conn.scheme.PlainSocketFactory;
import org.apache.ogt.http.conn.scheme.Scheme;
import org.apache.ogt.http.conn.scheme.SchemeRegistry;
import org.apache.ogt.http.impl.client.DefaultHttpClient;
import org.apache.ogt.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
/**
* Organizes Breadcrumbs tasks based on demands on the BaseAdapter functions
*
* @version $Id:$
* @author rene (c) Apr 24, 2011, Sogeti B.V.
*/
public class BreadcrumbsAdapter extends BaseAdapter implements Observer
{
private static final String TAG = "OGT.BreadcrumbsAdapter";
public static final String OAUTH_TOKEN = "breadcrumbs_oauth_token";
public static final String OAUTH_TOKEN_SECRET = "breadcrumbs_oauth_secret";
public static final boolean DEBUG = false;
boolean mAuthorized;
private Context mContext;
private LayoutInflater mInflater;
private BreadcrumbsTracks mTracks;
private DefaultHttpClient mHttpClient;
private GetBreadcrumbsBundlesTask mPlannedBundleTask;
private Queue<GetBreadcrumbsTracksTask> mPlannedTrackTasks;
private boolean mFinishing;
private OnSharedPreferenceChangeListener tokenChangedListener;
private ProgressListener mListener;
public BreadcrumbsAdapter(Context ctx, ProgressListener listener)
{
super();
mContext = ctx;
mListener = listener;
mInflater = LayoutInflater.from(mContext);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
ClientConnectionManager cm = new ThreadSafeClientConnManager(schemeRegistry);
mHttpClient = new DefaultHttpClient(cm);
mTracks = new BreadcrumbsTracks(mContext.getContentResolver());
mTracks.addObserver(this);
mPlannedTrackTasks = new LinkedList<GetBreadcrumbsTracksTask>();
}
public boolean connectionSetup()
{
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String token = prefs.getString(OAUTH_TOKEN, "");
String secret = prefs.getString(OAUTH_TOKEN_SECRET, "");
mAuthorized = !"".equals(token) && !"".equals(secret);
if (mAuthorized)
{
CommonsHttpOAuthConsumer consumer = getOAuthConsumer();
if (mTracks.readCache(mContext))
{
new GetBreadcrumbsActivitiesTask(mContext, this, mListener, mHttpClient, consumer).execute();
mPlannedBundleTask = new GetBreadcrumbsBundlesTask(mContext, this, mListener, mHttpClient, consumer);
}
}
return mAuthorized;
}
public CommonsHttpOAuthConsumer getOAuthConsumer()
{
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String token = prefs.getString(OAUTH_TOKEN, "");
String secret = prefs.getString(OAUTH_TOKEN_SECRET, "");
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(mContext.getString(R.string.CONSUMER_KEY), mContext.getString(R.string.CONSUMER_SECRET));
consumer.setTokenWithSecret(token, secret);
return consumer;
}
public void removeAuthentication()
{
Log.w( TAG, "Removing Breadcrumbs OAuth tokens");
Editor e = PreferenceManager.getDefaultSharedPreferences(mContext).edit();
e.remove(OAUTH_TOKEN);
e.remove(OAUTH_TOKEN_SECRET);
e.commit();
}
/*
* (non-Javadoc)
* @see android.widget.Adapter#getCount()
*/
public int getCount()
{
if (mAuthorized)
{
return mTracks.positions();
}
else
{
return 1;
}
}
/*
* (non-Javadoc)
* @see android.widget.Adapter#getItem(int)
*/
public Object getItem(int position)
{
if (mAuthorized)
{
return mTracks.getItemForPosition(position);
}
else
{
return Constants.BREADCRUMBS_CONNECT;
}
}
/*
* (non-Javadoc)
* @see android.widget.Adapter#getItemId(int)
*/
public long getItemId(int position)
{
return position;
}
/*
* (non-Javadoc)
* @see android.widget.Adapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent)
{
View view = null;
if (mAuthorized)
{
int type = getItemViewType(position);
if (convertView == null)
{
switch (type)
{
case Constants.BREADCRUMBS_BUNDLE_ITEM_VIEW_TYPE:
view = mInflater.inflate(R.layout.breadcrumbs_bundle, null);
break;
case Constants.BREADCRUMBS_TRACK_ITEM_VIEW_TYPE:
view = mInflater.inflate(R.layout.breadcrumbs_track, null);
break;
default:
view = new TextView(null);
break;
}
}
else
{
view = convertView;
}
Pair<Integer, Integer> item = mTracks.getItemForPosition(position);
String name;
switch (type)
{
case Constants.BREADCRUMBS_BUNDLE_ITEM_VIEW_TYPE:
name = mTracks.getValueForItem((Pair<Integer, Integer>) item, BreadcrumbsTracks.NAME);
((TextView) view.findViewById(R.id.listitem_name)).setText(name);
break;
case Constants.BREADCRUMBS_TRACK_ITEM_VIEW_TYPE:
TextView nameView = (TextView) view.findViewById(R.id.listitem_name);
TextView dateView = (TextView) view.findViewById(R.id.listitem_from);
nameView.setText(mTracks.getValueForItem(item, BreadcrumbsTracks.NAME));
String dateString = mTracks.getValueForItem(item, BreadcrumbsTracks.ENDTIME);
if(dateString != null)
{
Long date = GpxParser.parseXmlDateTime(dateString);
dateView.setText(date.toString());
}
break;
default:
view = new TextView(null);
break;
}
}
else
{
if (convertView == null)
{
view = mInflater.inflate(R.layout.breadcrumbs_connect, null);
}
else
{
view = convertView;
}
((TextView) view).setText(R.string.breadcrumbs_connect);
}
return view;
}
@Override
public int getViewTypeCount()
{
int types = 4;
return types;
}
@Override
public int getItemViewType(int position)
{
if (mAuthorized)
{
Pair<Integer, Integer> item = mTracks.getItemForPosition(position);
if (item.first == Constants.BREADCRUMBS_BUNDLE_ITEM_VIEW_TYPE)
{
if (!mFinishing && !mTracks.areTracksLoaded(item) && !mTracks.areTracksLoadingScheduled(item))
{
mPlannedTrackTasks.add(new GetBreadcrumbsTracksTask(mContext, this, mListener, mHttpClient, getOAuthConsumer(), item.second));
mTracks.addTracksLoadingScheduled(item);
executeNextTask();
}
}
return item.first;
}
else
{
return Constants.BREADCRUMBS_CONNECT_ITEM_VIEW_TYPE;
}
}
@Override
public boolean areAllItemsEnabled()
{
return false;
};
@Override
public boolean isEnabled(int position)
{
int itemViewType = getItemViewType(position);
return itemViewType == Constants.BREADCRUMBS_TRACK_ITEM_VIEW_TYPE || itemViewType == Constants.BREADCRUMBS_CONNECT_ITEM_VIEW_TYPE;
}
public BreadcrumbsTracks getBreadcrumbsTracks()
{
return mTracks;
}
public synchronized void finishedTask()
{
executeNextTask();
}
private synchronized void executeNextTask()
{
if (mPlannedBundleTask != null)
{
mPlannedBundleTask.execute();
mPlannedBundleTask = null;
}
else
{
GetBreadcrumbsTracksTask next = mPlannedTrackTasks.poll();
if (next != null)
{
GetBreadcrumbsTracksTask task = (GetBreadcrumbsTracksTask) next;
task.execute();
}
}
}
public synchronized void shutdown()
{
if (tokenChangedListener != null)
{
PreferenceManager.getDefaultSharedPreferences(mContext).unregisterOnSharedPreferenceChangeListener(tokenChangedListener);
}
mAuthorized = false;
mFinishing = true;
mPlannedBundleTask = null;
mPlannedTrackTasks.clear();
mHttpClient.getConnectionManager().shutdown();
mHttpClient = null;
mTracks.persistCache(mContext);
}
public void startDownloadTask(Context context, ProgressListener listener, Pair<Integer, Integer> track)
{
new DownloadBreadcrumbsTrackTask(context, listener, this, mHttpClient, getOAuthConsumer(), track).execute();
}
public void startUploadTask(Context context, ProgressListener listener, Uri trackUri, String name)
{
new UploadBreadcrumbsTrackTask(context, this, listener, mHttpClient, getOAuthConsumer(), trackUri, name).execute();
}
public boolean isOnline()
{
return mAuthorized;
}
public void requestBreadcrumbsOauthToken(final Activity activity)
{
tokenChangedListener = new OnSharedPreferenceChangeListener()
{
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if (OAUTH_TOKEN.equals(key))
{
PreferenceManager.getDefaultSharedPreferences(mContext).unregisterOnSharedPreferenceChangeListener(tokenChangedListener);
activity.runOnUiThread(new Runnable()
{
public void run()
{
connectionSetup();
}
});
}
}
};
PreferenceManager.getDefaultSharedPreferences(mContext).registerOnSharedPreferenceChangeListener(tokenChangedListener);
Intent i = new Intent(mContext.getApplicationContext(), PrepareRequestTokenActivity.class);
i.putExtra(PrepareRequestTokenActivity.OAUTH_TOKEN_PREF, OAUTH_TOKEN);
i.putExtra(PrepareRequestTokenActivity.OAUTH_TOKEN_SECRET_PREF, OAUTH_TOKEN_SECRET);
i.putExtra(PrepareRequestTokenActivity.CONSUMER_KEY, mContext.getString(R.string.CONSUMER_KEY));
i.putExtra(PrepareRequestTokenActivity.CONSUMER_SECRET, mContext.getString(R.string.CONSUMER_SECRET));
i.putExtra(PrepareRequestTokenActivity.REQUEST_URL, Constants.REQUEST_URL);
i.putExtra(PrepareRequestTokenActivity.ACCESS_URL, Constants.ACCESS_URL);
i.putExtra(PrepareRequestTokenActivity.AUTHORIZE_URL, Constants.AUTHORIZE_URL);
mContext.startActivity(i);
}
public void update(Observable observable, Object data)
{
notifyDataSetChanged();
}
}