/**
*
* @author Peter Brinkmann (peter.brinkmann@gmail.com)
*
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
*/
package org.puredata.android.scenes;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class SceneDataBase {
public static final String TABLE_SCENES = "scenes";
public static final String TABLE_RECORDINGS = "recordings";
public interface Column {
String getLabel();
}
public static enum SceneColumn implements Column {
ID("_id", "integer primary key autoincrement, "),
SCENE_ARTIST("author", "text not null, "),
SCENE_TITLE("name", "text not null, "),
SCENE_INFO("description", "text not null, "),
SCENE_CATEGORY("category", "text, "),
SCENE_ID("sceneId", "text, "),
SCENE_DIRECTORY("directory", "text unique not null");
private final String label;
private final String type;
private SceneColumn(String label, String type) {
this.label = label;
this.type = type;
}
@Override
public String getLabel() {
return label;
}
}
public static enum RecordingColumn implements Column {
ID("_id", "integer primary key autoincrement, "),
RECORDING_PATH("path", "text not null, "),
RECORDING_TIMESTAMP("time", "integer not null, "), // Unix time
RECORDING_DURATION("duration", "integer not null, "),
RECORDING_DESCRIPTION("description", "text, "),
RECORDING_LATITUDE("latitude", "real, "),
RECORDING_LONGITUDE("longitude", "real, "),
SCENE_ID("scene_id", "integer not null");
private final String label;
private final String type;
private RecordingColumn(String label, String type) {
this.label = label;
this.type = type;
}
@Override
public String getLabel() {
return label;
}
}
private final SQLiteDatabase db;
public SceneDataBase(Context context) {
SceneDataBaseHelper helper = new SceneDataBaseHelper(context);
db = helper.getWritableDatabase();
}
public void close() {
db.close();
}
public long addScene(File sceneFolder) throws IOException {
Map<String, String> sceneInfo;
try {
sceneInfo = readInfo(sceneFolder);
} catch (Exception e) {
throw new IOException(e.getMessage());
}
ContentValues values = new ContentValues();
for (SceneColumn column : SceneColumn.values()) {
String name = column.label;
values.put(name, sceneInfo.get(name));
}
values.put(SceneColumn.SCENE_DIRECTORY.label, sceneFolder.getAbsolutePath());
return db.insert(TABLE_SCENES, null, values);
}
public long addRecording(String path, long time, long duration, double longitude, double latitude, long sceneId) {
ContentValues values = new ContentValues();
values.put(RecordingColumn.RECORDING_PATH.label, path);
values.put(RecordingColumn.RECORDING_TIMESTAMP.label, time);
values.put(RecordingColumn.RECORDING_DURATION.label, duration);
values.put(RecordingColumn.RECORDING_LONGITUDE.label, longitude);
values.put(RecordingColumn.RECORDING_LATITUDE.label, latitude);
values.put(RecordingColumn.SCENE_ID.label, sceneId);
return db.insert(TABLE_RECORDINGS, null, values);
}
public void deleteScene(long id) throws IOException {
Cursor cursor = getScene(id);
String path = getString(cursor, SceneColumn.SCENE_DIRECTORY);
cursor.close();
if (new File(path).exists()) {
Runtime.getRuntime().exec("rm -r " + path);
}
db.delete(TABLE_SCENES, sceneIdClause(id), null);
}
public void deleteRecording(long id) throws IOException {
Cursor cursor = getRecording(id);
String path = getString(cursor, RecordingColumn.RECORDING_PATH);
cursor.close();
if (new File(path).exists()) {
Runtime.getRuntime().exec("rm " + path);
}
db.delete(TABLE_RECORDINGS, recordingIdClause(id), null);
}
public Cursor getAllScenes() {
return db.query(TABLE_SCENES, null, null, null, null, null, SceneColumn.SCENE_TITLE.label);
}
public Cursor getAllRecordings() {
return db.query(TABLE_RECORDINGS, null, null, null, null, null, RecordingColumn.RECORDING_TIMESTAMP.label);
}
public Cursor getScene(long id) {
Cursor cursor = db.query(TABLE_SCENES, null, sceneIdClause(id), null, null, null, null);
cursor.moveToFirst();
return cursor;
}
private String sceneIdClause(long id) {
return SceneColumn.ID.label + " = " + id;
}
public Cursor getRecording(long id) {
Cursor cursor = db.query(TABLE_RECORDINGS, null, recordingIdClause(id), null, null, null, null);
cursor.moveToFirst();
return cursor;
}
private String recordingIdClause(long id) {
return RecordingColumn.ID.label + " = " + id;
}
public void setRecordingDescription(long id, String description) {
ContentValues values = new ContentValues();
values.put(RecordingColumn.RECORDING_DESCRIPTION.label, description);
db.update(TABLE_RECORDINGS, values, recordingIdClause(id), null);
}
public static String getString(Cursor cursor, Column column) {
return getString(cursor, column.getLabel());
}
public static String getString(Cursor cursor, String column) {
return cursor.getString(cursor.getColumnIndex(column));
}
public static long getLong(Cursor cursor, Column column) {
return getLong(cursor, column.getLabel());
}
public static long getLong(Cursor cursor, String column) {
return cursor.getLong(cursor.getColumnIndex(column));
}
public static double getDouble(Cursor cursor, Column column) {
return getDouble(cursor, column.getLabel());
}
public static double getDouble(Cursor cursor, String column) {
return cursor.getDouble(cursor.getColumnIndex(column));
}
private static class SceneDataBaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "scenedb";
public static final int DATABASE_VERSION = 1001;
public SceneDataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
StringBuilder create = new StringBuilder("create table " + TABLE_SCENES + " (");
for (SceneColumn column: SceneColumn.values()) {
create.append(column.label);
create.append(" ");
create.append(column.type);
}
create.append(");");
db.execSQL(create.toString());
create = new StringBuilder("create table " + TABLE_RECORDINGS + " (");
for (RecordingColumn column: RecordingColumn.values()) {
create.append(column.label);
create.append(" ");
create.append(column.type);
}
create.append(");");
db.execSQL(create.toString());
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion != oldVersion) {
db.execSQL("drop table if exists " + TABLE_SCENES + ";");
db.execSQL("drop table if exists " + TABLE_RECORDINGS + ";");
onCreate(db);
}
}
}
private Map<String, String> readInfo(File sceneFolder)
throws ParserConfigurationException, SAXException, IOException {
final Map<String, String> values = new HashMap<String, String>();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
sp.parse(new File(sceneFolder, "Info.plist"), new DefaultHandler() {
private String key = "", val = "";
private boolean expectKey;
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
expectKey = localName.equalsIgnoreCase("key");
if (expectKey) {
key = val = "";
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String s = new String(ch, start, length);
if (expectKey) {
key += s;
} else {
val += s;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
key = key.trim();
val = val.trim();
if (key.length() > 0) {
values.put(key, val);
}
}
});
return values;
}
}