package de.tum.in.tumcampusapp.managers;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import org.simpleframework.xml.core.Persister;
import java.util.Date;
import de.tum.in.tumcampusapp.auxiliary.DateUtils;
import de.tum.in.tumcampusapp.auxiliary.Utils;
import de.tum.in.tumcampusapp.models.tumo.Error;
/**
* TUMOnline lock manager: prevent too many requests send to TUMO
*/
public class TumManager extends AbstractManager {
private static final int COL_URL = 0;
private static final int COL_ERROR = 1;
private static final int COL_TIMESTAMP = 2;
private static final int COL_LOCKED_FOR = 3;
private static final int COL_ACTIVE = 4;
private static final int MAX_AGE = CacheManager.VALIDITY_ONE_DAY / 4; //Maximum length of a lock
private static final int DEFAULT_LOCK = 60; //Base value for the first error: 60 seconds
public static class reqStatus {
private String url;
public String error;
private Date timestamp;
private int lockedFor;
private int active;
}
/**
* Constructor, open/create database, create table if necessary
*
* @param context Context
*/
public TumManager(Context context) {
super(context);
// create table if needed
db.execSQL("CREATE TABLE IF NOT EXISTS tumLocks (url VARCHAR UNIQUE, error VARCHAR, timestamp VARCHAR, lockedFor INT, active INT)");
// Delete obsolete entries
db.execSQL("DELETE FROM tumLocks WHERE datetime() > datetime(strftime('%s',timestamp) + " + TumManager.MAX_AGE + ", 'unixepoch') AND active=0");
}
public String checkLock(String url) {
//Deactivate all expired locks
db.execSQL("UPDATE tumLocks SET active=0 WHERE datetime() > datetime(strftime('%s',timestamp) + lockedFor, 'unixepoch') AND active=1");
//Try to get a result
reqStatus r = this.getLock(url);
//If we got nothing there is no lock - or if it isn't active
if (r == null || r.active == 0) {
return null;
}
//Otherwise return the error message
return r.error;
}
public void releaseLock(String url) {
//Enter it into the Databse
try {
db.execSQL("REPLACE INTO tumLocks (url, active) VALUES (?, 0)", new String[]{url});
} catch (SQLiteException e) {
Utils.log(e);
}
}
public reqStatus getLock(String url) {
reqStatus result = null;
try {
Cursor c = db.rawQuery("SELECT * FROM tumLocks WHERE url=?", new String[]{url});
if (c.getCount() == 1) {
c.moveToFirst();
result = new reqStatus();
result.url = c.getString(COL_URL);
result.error = c.getString(COL_ERROR);
result.timestamp = DateUtils.parseSqlDate(c.getString(COL_TIMESTAMP));
result.lockedFor = c.getInt(COL_LOCKED_FOR);
result.active = c.getInt(COL_ACTIVE);
}
c.close();
} catch (SQLiteException e) {
Utils.log(e);
}
return result;
}
public String addLock(String url, String data) {
//Check if we have a lock already
reqStatus r = this.getLock(url);
int lockTime = TumManager.DEFAULT_LOCK;
if (r != null) {
//Double the lock time with each failed request
lockTime = r.lockedFor * 2;
//If we are above the limit reset to the limit
if (lockTime > TumManager.MAX_AGE) {
lockTime = TumManager.MAX_AGE;
}
}
//Try to parse the error
String msg = "";
try {
Error res = new Persister().read(Error.class, data);
msg = res.getMessage();
} catch (Exception e) {
Utils.log(e);
}
//Enter it into the Databse
db.execSQL("REPLACE INTO tumLocks (url, error, timestamp, lockedFor, active) VALUES (?, ?, datetime('now'), ?, 1)", new String[]{url, msg, String.valueOf(lockTime)});
return msg;
}
}