/**
* Copyright (C) 2013 Romain Guefveneu.
*
* This file is part of naonedbus.
*
* Naonedbus 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.
*
* Naonedbus 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.naonedbus.manager.impl;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import net.naonedbus.BuildConfig;
import net.naonedbus.bean.Ligne;
import net.naonedbus.bean.async.AsyncTaskInfo;
import net.naonedbus.bean.async.LignesTaskInfo;
import net.naonedbus.manager.SQLiteManager;
import net.naonedbus.manager.Unschedulable;
import net.naonedbus.provider.impl.LigneProvider;
import net.naonedbus.provider.table.LigneTable;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class LigneManager extends SQLiteManager<Ligne> implements Unschedulable<LignesTaskInfo> {
private static final String LOG_TAG = "LigneManager";
private static final boolean DBG = BuildConfig.DEBUG;
private static LigneManager sInstance;
private int mColId;
private int mColCode;
private int mColDepuis;
private int mColLettre;
private int mColVers;
private int mColCouleurBack;
private int mColCouleurFront;
private int mColType;
private Thread mLignesLoader;
private final ConcurrentLinkedQueue<LignesTaskInfo> mLignesTasks;
private final Object mLock = new Object();
private final Ligne.Builder mBuilder;
private boolean mIsIndexed;
public static synchronized LigneManager getInstance() {
if (sInstance == null) {
sInstance = new LigneManager();
}
return sInstance;
}
protected LigneManager() {
super(LigneProvider.CONTENT_URI);
mLignesTasks = new ConcurrentLinkedQueue<LignesTaskInfo>();
mBuilder = new Ligne.Builder();
}
/**
* Récupérer les lignes selon un type donné
*
* @param contentResolver
* @param idType
* @return Les lignes correspondants au type
*/
public List<Ligne> getLignesByType(final ContentResolver contentResolver, final Integer idType) {
final Uri.Builder builder = LigneProvider.CONTENT_URI.buildUpon();
builder.path(LigneProvider.LIGNE_TYPE_URI_PATH_QUERY);
builder.appendPath(Integer.toString(idType));
final Cursor c = contentResolver.query(builder.build(), null, null, null, null);
return getFromCursor(c);
}
/**
* Récupérer les lignes selon un mot clé.
*
* @param contentResolver
* @param keyword
* @return Les lignes correspondants au mot clé
*/
public Cursor getLignesSearch(final ContentResolver contentResolver, final String keyword) {
final Uri.Builder builder = LigneProvider.CONTENT_URI.buildUpon();
builder.appendPath(keyword);
return contentResolver.query(builder.build(), null, null, null, null);
}
@Override
public void onIndexCursor(final Cursor c) {
mColId = c.getColumnIndex(LigneTable._ID);
mColCode = c.getColumnIndex(LigneTable.CODE);
mColDepuis = c.getColumnIndex(LigneTable.DEPUIS);
mColLettre = c.getColumnIndex(LigneTable.LETTRE);
mColVers = c.getColumnIndex(LigneTable.VERS);
mColCouleurBack = c.getColumnIndex(LigneTable.COULEUR_BACK);
mColCouleurFront = c.getColumnIndex(LigneTable.COULEUR_FRONT);
mColType = c.getColumnIndex(LigneTable.TYPE);
mIsIndexed = true;
}
@Override
public Ligne getSingleFromCursor(final Cursor c) {
if (!mIsIndexed)
onIndexCursor(c);
mBuilder.setId(c.getInt(mColId));
mBuilder.setCode(c.getString(mColCode));
mBuilder.setDepuis(c.getString(mColDepuis));
mBuilder.setLettre(c.getString(mColLettre));
mBuilder.setVers(c.getString(mColVers));
mBuilder.setCouleurBack(c.getInt(mColCouleurBack));
mBuilder.setCouleurFront(c.getInt(mColCouleurFront));
mBuilder.setSection(c.getInt(mColType));
return mBuilder.build();
}
public List<Ligne> getLignesFromStation(final ContentResolver contentResolver, final int idStation) {
final Uri.Builder builder = LigneProvider.CONTENT_URI.buildUpon();
builder.path(LigneProvider.LIGNE_STATION_URI_PATH_QUERY);
builder.appendQueryParameter("idStation", String.valueOf(idStation));
final Cursor cursor = contentResolver.query(builder.build(), null, null, null, null);
return getFromCursor(cursor);
}
/**
* Programmer la récupération des lignes de manière asynchrone.
*
* @param contentResolver
* @param idStation
* L'id de la station dont les lignes sont à charger.
* @param callback
* Un {@code Handler} receptionnant le resultat dans {@code obj}
* sous forme de {@code List<Ligne>} .
*/
public LignesTaskInfo scheduleGetLignesFromStation(final Context context, final int idStation,
final Handler callback) {
final LignesTaskInfo task = new LignesTaskInfo(context, idStation, callback);
if (DBG)
Log.d(LOG_TAG, "schedule :\t" + task);
mLignesTasks.add(task);
if (mLignesLoader == null || !mLignesLoader.isAlive()) {
mLignesLoader = new Thread(lignesFromStationLoader);
mLignesLoader.start();
} else if (mLignesLoader.getState().equals(Thread.State.TIMED_WAITING)) {
synchronized (mLock) {
mLock.notify();
}
}
return task;
}
@Override
public void unschedule(final LignesTaskInfo task) {
if (DBG)
Log.d(LOG_TAG, "unschedule :\t" + task);
mLignesTasks.remove(task);
}
/**
* Loader pour le chargement des lignes asynchrone.
*/
private final Runnable lignesFromStationLoader = new Runnable() {
@Override
public void run() {
AsyncTaskInfo<Integer> task;
List<Ligne> lignes;
Handler handler;
Message message;
while ((task = mLignesTasks.poll()) != null) {
lignes = getLignesFromStation(task.getContext().getContentResolver(), task.getTag());
handler = task.getHandler();
message = new Message();
message.obj = lignes;
handler.sendMessage(message);
if (mLignesTasks.isEmpty()) {
synchronized (mLock) {
try {
mLock.wait(2000);
} catch (final InterruptedException e) {
}
}
}
}
}
};
@Override
protected ContentValues getContentValues(final Ligne item) {
return null;
}
}