Back to project page Abstract-Model.
The source code is released under:
Apache License
If you think the Android project Abstract-Model listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.logician.abstractModel; /*from w w w .jav a2 s.c o m*/ import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.util.Log; /** * This class allows you to create a Java/Android data structure that can translate seamlessly * to an SQLiteDatabase and back. * * <p/> * * This class is designed to make database access simple.<br/> * All you have to do is declare fields in the subclass, define the table with getTableName() and getColumns(), * and use {@link #fromRow(Row)} and {@link #toRow(Row)} to retrieve and store the values, respectively. * * <p/> * * Objects of Model subclasses are meant to be disposable. For example, it is perfectly acceptable * to write {@code new Model().getTableSQL()} in your SQLiteOpenHelper's onCreate() callback. * * <p/> Of course, it is best to be conservative.<br/> * * <p/> {@literal See} the package com.logician.abstractModel.examples for sample implementations and usage. * * <p/> Note: it is recommended to have a static {@link Model.Factory} member for convenient mass-instantiation from a Cursor. * * <p> The Model will automatically try to retrieve the default "index" primary key when it's created from * a Cursor. This is used to make update() and delete() commands simpler. If you use a different column * as a primary key, then you need to override getIndex() to provide the proper value. * * <p> Also note that this class implements {@link JSONSerializable}. Since a Model can store and retrieve JSONObjects, * this implies that Models can nest. Keep in mind that JSONObjects are stored as Strings in the database and need to be parsed, so many nested models * will require quite a bit of processing power to instantiate. It is recommended that if Models are deeply nested to do the work in an * {@link android.os.AsyncTask} or use an {@link AsyncModelFactory}. * * * @see SQLiteOpenHelper * @see Column * @see Row * * @author Logician * */ public abstract class Model implements JSONSerializable{ /** * An empty constructor is required because many throwaway objects are * created in many different contexts. <br/> * * Instead of using a constructor, simply create an empty object and set the fields manually, * or use a static factory method. */ public Model(){ } /** * The default column name for the automatically created primary key in SQLite. */ public static final String ROWID = "rowid"; /** * The default projection you should use with any {@code query} method call * that takes it, or a {@code columns[]} argument, to make sure that ROWID * ends up in the cursor. * * @see SQLiteDatabase#query(String, String[], String, String[], String, String, String) * @see ContentProvider#query(android.net.Uri, String[], String, String[], String) */ public static final String[] PROJECTION = {ROWID, "*"}; private long rowid = -1; private boolean updated = false; private boolean isNew = true; @Override public boolean equals(Object o){ return o instanceof Model && equals((Model) o); } /** * Compare these two Models and return if they are equal. * Default implementation returns {@code getTableName.equals(model.getTableName)}. * <br> * You should override this if you are comparing two instances of the same subclass * to customize comparison criteria. See example class User for a sample * implementation. * * @param model The model to compare to. * @return If the Models are equal. Criteria depends on implementation. */ public boolean equals(Model model){ return getTableName().equals(model.getTableName()); } /** * Get the primary key of this Model if one could be found, -1 otherwise. * <p> * SQLite automatically creates a primary key column named {@value #ROWID}. <br/> * The Model class will automatically attempt to retrieve it from a Cursor, * Bundle, or JSONObject. * <br> Thusly, the Model will also place the value * returned from this method in a Bundle or JSONObject mapped to {@link #ROWID}. * <p> * If a ROWID could not be found, or if the Model is new, then this method * returns -1. * <p> * You should override this method if you intend to create your own * primary key. * * @return The ROWID of this Model if one is available, -1 otherwise. */ public long getRowId(){ return rowid; } /** * Get the CREATE TABLE SQL for this Model, to be used in SQLiteOpenHelper.onCreate(), onUpgrade(), onDowngrade(), etc. * * @see SQLiteOpenHelper#onCreate(SQLiteDatabase) * @see SQLiteOpenHelper#onUpgrade(SQLiteDatabase, int, int) * @return The CREATE TABLE SQL for this Model. */ public final String getTableSQL() { return "CREATE TABLE IF NOT EXISTS " + getTableName() + " " + getColumnsSQL(); } private String getColumnsSQL(){ StringBuilder SQL = new StringBuilder("("); boolean first = true; for(Column col : getColumns()){ if(!first) SQL.append(", "); SQL.append(col.getColumnSQL()); first = false; } SQL.append(')'); return SQL.toString(); } /** * Return the name for this Model's table in the database. * * @return The table name for this Model. */ public abstract String getTableName(); /** * Return the array of Columns that will be contained in this Model. * Used to generate the Model's CREATE TABLE SQL. * * @see Column * @return The array of {@link Column}s contained in this Model. */ public abstract Column[] getColumns(); /** * Called by fromCursor(), fromBundle() and fromJSONObject(). * The column names map to objects of the respective columns' types. * * Do <b>not</b> retain the Row object as it is used internally in the Model * once the method returns. * * @see Row * @see #fromCursor(Cursor) * @see #fromBundle(Bundle) * @see #fromJSONObject(JSONObject) * @param row The Row object containing the values for this Model. */ public abstract void fromRow(Row row); /** * Called by toContentValues(), toJSONObject() and toBundle(). * Place values in the row using {@code Row.put()} * using the respective column names as the keys. * * Do <b>not</b> retain the Row object as it is used internally in the Model * once the method returns. * * @see Row * @see #toBundle() * @see #toContentValues() * @see #toJSONObject() * @param row The Row object in which to place this Model's values. */ public abstract void toRow(Row row); /** * Get the display values from this Model for use * in a ModelListAdapter. Default implentation * calls toRow(row). Override this if you want to display * * @see ModelListAdapter * @param row The Row in which to place values, mapped to the keys passed to * {@link ModelListAdapter#ModelListAdapter(Context, List, String[], int, int[])}. */ public void getDisplayValues(Row row){ toRow(row); } /** * Output the values of this model to a ContentValues object. * * @see ContentValues * @see SQLiteDatabase#insert(String, String, ContentValues) * @return A ContentValues object containing the value mappings of this Model. */ public final ContentValues toContentValues(){ final ContentValues cV = new ContentValues(); toRow(new ContentValuesRow(cV)); return cV; } /** * * Use this to instantiate a Model from a Cursor. * If your Cursor has more than one row, then you might want to use {@link Model.Factory#listFromCursor(Cursor)} * instead. * <p> * Make sure you pass {@code null} to {@code String columns[]} (the second argument) in * {@link SQLiteDatabase#query(String, String[], String, String[], String, String, String)} * to get all the columns (including the default {@value #ROWID} column). * <p> * Otherwise, any unspecified columns in the query will have their respective * fields in the Model set to {@code null} or an arbitrary value based on the type. * * @param cursor A Cursor returned by SQLiteDatabase.query() or ContentProvider.query(). */ public final void fromCursor(Cursor cursor){ if(cursor.isAfterLast() || cursor.isBeforeFirst() || cursor.getCount() == 0) return; int index = cursor.getColumnIndex(ROWID); if(Util.DEBUG) Log.d("Model", "ROWID column index: "+ Integer.toString(index)); if(index >= 0) rowid = cursor.getLong(index); fromRow(new CursorRow(cursor)); isNew = false; } /** * Convert this Model to a JSONObject. * <p> * Because of the nature of implementing the Row interface, * any JSONExceptions will simply be wrapped in a RuntimeException and re-thrown. * <p> * Note: since JSONObjects cannot store a [{@code byte[]} object properly, * the associated methods will throw an {@link UnsupportedOperationException}. * * @see JSONException * @see JSONObject * @return A JSONObject containing the values of this Model mapped to their respective Columns. */ public final JSONObject toJSONObject(){ JSONObject jO = new JSONObject(); try { jO.put(ROWID, getRowId()); } catch (JSONException e) { throw new RuntimeException(e); } toRow(new JSONObjectRow(jO)); return jO; } /** * Convert this Model from a JSONObject. * <p> * The abstraction uses the opt<i>Type</i>() methods in JSONObject to * retrieve values because there is no way to safely handle the JSONExceptions * thrown by get<i>Type</i>(). {@link #toJSONObject()} wraps the exception in * a RuntimeException and re-throws because there is no other option. * <p> * Note: since JSONObjects cannot store a [{@code byte[]} object properly, * the associated methods will throw an {@link UnsupportedOperationException}. * @see JSONObject * @param jO The JSONObject from which to retrieve this Model's values. * */ public final void fromJSONObject(JSONObject jO){ jO.optLong(ROWID, rowid); fromRow(new JSONObjectRow(jO)); } /** * Convert this model to a {@link Bundle} that can be supplied as an extra in an {@link android.content.Intent}. * Good whenever you need to pass a Model's data through an IPC like {@link Context#startActivity(android.content.Intent)} or {@link Context#startService(android.content.Intent)}. * You can reinstantiate it on the other side with fromBundle(). * * @see #fromBundle(Bundle) * @see android.content.Intent#putExtra(String, Bundle) * * @return A Bundle containing the column-value mappings for this Model. */ public final Bundle toBundle(){ Bundle bundle = new Bundle(); bundle.putLong(ROWID, rowid); toRow(new BundleRow(bundle)); return bundle; } /** * Retrieve this Model's values from the supplied Bundle. Good for reinstantiating a Model * after passing it through an Intent with toBundle(). * * @see #toBundle() * @see android.content.Intent#getBundleExtra(String name) * @param bundle The Bundle in which to place values. * @throws JSONException */ public final void fromBundle(Bundle bundle) throws JSONException{ rowid = bundle.getLong(ROWID, rowid); fromRow(new BundleRow(bundle)); } /** * Copy values from the supplied Model. * Default implementation does nothing. * * @see #toRow(Row) * @see #fromRow(Row) * @param model The Model to copy from. */ public void copyFrom(Model model){} /** * Returns the internal {@code updated} * flag of this Model. Useful when iterating over * a List to update in the database. * * @see #setUpdated() * @return The value of {@code private boolean updated}. */ public boolean getUpdated(){ return updated; } /** * Sets the internal {@code updated} flag to {@code true}. * Use this with getUpdated() to know which Models to update * when * * @see #getUpdated() */ public void setUpdated(){ updated = true; } /** * Returns {@code false} if this Model was instantiated with * fromBundle(), fromJSONObject(), or fromCursor(); * {@code true} otherwise. * * @see #fromBundle(Bundle) * @see #fromCursor(Cursor) * @see #fromJSONObject(JSONObject) * */ public boolean getIsNew(){ return isNew; } /** * Returns a String containing a comprehensive breakdown of this Model, * including its name, ROWID, and key-value mappings. * <p> * Note: since this can be an expensive method call for large Models, * you should only use this method for debugging purposes. * <p> * Remove calls to this method for production builds, override it, or use * {@code if(BuildConfig.DEBUG)}. * * @see android.widget.ArrayAdapter * @return A String containing debug information for this Model. */ @Override public String toString(){ ToStringRow toStringRow = new ToStringRow(getTableName(), getRowId()); toRow(toStringRow); return toStringRow.toString(); } /** * A convenience class for converting Lists of Models to and from JSONArrays and from Cursors. * * * @see List * @author Logician * * @param <T> The {@link Model} subclass that this factory will be manufacturing. */ public abstract static class Factory<T extends Model> { /** * Just a way of constructing a new Model subclass without using reflection. * * @return {@code new T()} */ public abstract T getModel(); /** * Iterates through the given Cursor, * starting at its current position; * constructs a new Model object for each row, * and instantiates it with fromCursor(). * <p> * Use with {@code SQLiteDatabase.query(Model.getTableName(), null, null, null, null, null, null)} * to get a Cursor that contains every row in the table. * <p> * Be sure of the Cursor's position before calling this method. * If you're using the whole Cursor, call {@link Cursor#moveToFirst()}. * * @see Model#fromCursor(Cursor) * @param cursor The Cursor to retrieve values from. * @return An ArrayList containing all the Models that could be created from this Cursor. */ public List<T> listFromCursor(Cursor cursor){ int count = cursor.getCount(); if(Util.DEBUG) Log.d("Model.Factory("+getModel().getTableName()+")", "Cursor length: "+ Integer.toString(count)); ArrayList<T> ts = new ArrayList<T>(); if(!cursor.isBeforeFirst() &&!cursor.isBeforeFirst() && cursor.getCount() > 0) while(!cursor.isClosed()){ do{ T t = getModel(); t.fromCursor(cursor); ts.add(t); }while(cursor.moveToNext()); break; } return ts; } /** * Constructs a List of Models from a JSONArray. * The method assumes that the JSONArray contains only JSONObjects * that can be subsequently passed to Model.fromJSONObject() without issue. * * @see Model#fromJSONObject(JSONObject) * @param jA A {@link JSONArray} containing Models in the form of JSONObjects. * @return A List containing all the models that could be gleaned from the JSONArray. */ public List<T> listFromJSONArray(JSONArray jA) { ArrayList<T> ts = new ArrayList<T>(jA.length()); for(int i = 0; i < jA.length(); i++){ T t = getModel(); try { t.fromJSONObject(jA.getJSONObject(i)); } catch (JSONException e) { throw new RuntimeException(e); } ts.add(t); } return ts; } /** * Converts an ArrayList of Models to a JSONArray. * * @param ts An ArrayList containing the Models to convert. * @return A JSONArray containing JSONObject representations of the Models. */ public JSONArray listToJSONArray(List<T> ts) throws JSONException{ JSONArray jA = new JSONArray(); for(T t : ts) jA.put(t.toJSONObject()); return jA; } } /** * An interface to abstract the input/output of data to and from assorted carrier objects. * * <p> * Methods that aren't expected to be called (like calling any of the * {@code put()} methods on a Row passed in {@link Model#fromRow(Row)} * may throw an {@link UnsupportedOperationException} depending on the implementation. * * @see Model#toRow(Row) * @see Model#fromRow(Row) * * @author Logician * */ public interface Row { public void put(String key, int value); public void put(String key, boolean value); public void put(String key, long value); public void put(String key, double value); public void put(String key, float value); public void put(String key, String value); public void put(String key, byte[] value); public void put(String key, JSONObject jO); public void put(String key, JSONArray jA); public void put(String key, JSONSerializable jS) throws JSONException; public void put(String key, BinarySerializable bS); public int getInt(String key); public int getInt(String key, int defaultValue); public boolean getBool(String key); public boolean getBool(String key, boolean defaultValue); public long getLong(String key); public long getLong(String key, long defaultValue); public double getDouble(String key); public double getDouble(String key, double defaultValue); public float getFloat(String key); public float getFloat(String key, float defaultValue); public String getString(String key); public String getString(String key, String defaultValue); public byte[] getByteArr(String key); public byte[] getByteArr(String key, byte[] defaultValue); public JSONObject getJSONObject(String key) throws JSONException; public JSONArray getJSONArray(String key) throws JSONException; public boolean containsKey(String key); } private static class BundleRow implements Row{ private final Bundle bundle; public BundleRow(Bundle bundle){ this.bundle = bundle; } @Override public void put(String key, int value) { bundle.putInt(key, value); } @Override public void put(String key, boolean value) { bundle.putBoolean(key, value); } @Override public void put(String key, long value) { bundle.putLong(key, value); } @Override public void put(String key, double value) { bundle.putDouble(key, value); } @Override public void put(String key, float value) { bundle.putFloat(key, value); } @Override public void put(String key, String value) { bundle.putString(key, value); } @Override public void put(String key, byte[] value) { bundle.putByteArray(key, value); } @Override public void put(String key, JSONObject jO) { bundle.putString(key, jO.toString()); } @Override public void put(String key, JSONArray jA) { bundle.putString(key, jA.toString()); } @Override public void put(String key, JSONSerializable jS) throws JSONException { bundle.putString(key, jS.toJSONObject().toString()); } @Override public void put(String key, BinarySerializable bS) { bundle.putByteArray(key, bS.toBinary()); } @Override public int getInt(String key) { return bundle.getInt(key); } @Override public int getInt(String key, int defaultValue) { return bundle.getInt(key, defaultValue); } @Override public boolean getBool(String key) { return bundle.getBoolean(key); } @Override public boolean getBool(String key, boolean defaultValue) { return bundle.getBoolean(key, defaultValue); } @Override public long getLong(String key) { return bundle.getLong(key); } @Override public long getLong(String key, long defaultValue) { return bundle.getLong(key, defaultValue); } @Override public double getDouble(String key) { return bundle.getDouble(key); } @Override public double getDouble(String key, double defaultValue) { return bundle.getDouble(key, defaultValue); } @Override public float getFloat(String key) { return bundle.getFloat(key); } @Override public float getFloat(String key, float defaultValue) { return bundle.getFloat(key, defaultValue); } @Override public String getString(String key) { return bundle.getString(key); } @Override public String getString(String key, String defaultValue) { return bundle.getString(key, defaultValue); } @Override public byte[] getByteArr(String key) { return bundle.getByteArray(key); } @Override public byte[] getByteArr(String key, byte[] defaultValue) { if(containsKey(key)) return bundle.getByteArray(key); else return defaultValue; } @Override public JSONObject getJSONObject(String key) throws JSONException { return new JSONObject(bundle.getString(key)); } @Override public JSONArray getJSONArray(String key) throws JSONException { return new JSONArray(bundle.getString(key)); } @Override public boolean containsKey(String key) { return bundle.containsKey(key); } } private static class JSONObjectRow implements Row{ private JSONObject jO; public JSONObjectRow(JSONObject jO){ this.jO = jO; } @Override public void put(String key, int value){ try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, boolean value) { try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, long value) { try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, double value) { try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, float value) { try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, String value) { try { jO.put(key, value); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, byte[] value) { throw new UnsupportedOperationException(); } @Override public void put(String key, JSONObject jO) { try { jO.put(key, jO); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, JSONArray jA){ try { jO.put(key, jA); } catch (JSONException e) { throw new RuntimeException(e); } } @Override public void put(String key, JSONSerializable jS) throws JSONException { jO.put(key, jS.toJSONObject()); } @Override public int getInt(String key) { return jO.optInt(key); } @Override public int getInt(String key, int defaultValue) { return jO.optInt(key, defaultValue); } @Override public boolean getBool(String key) { return jO.optBoolean(key); } @Override public boolean getBool(String key, boolean defaultValue) { return jO.optBoolean(key, defaultValue); } @Override public long getLong(String key) { return jO.optLong(key); } @Override public long getLong(String key, long defaultValue) { return jO.optLong(key, defaultValue); } @Override public double getDouble(String key){ return jO.optDouble(key); } @Override public double getDouble(String key, double defaultValue) { return jO.optDouble(key, defaultValue); } @Override public float getFloat(String key) { return (float) getDouble(key); } @Override public float getFloat(String key, float defaultValue) { return (float) jO.optDouble(key, defaultValue); } @Override public String getString(String key) { return jO.optString(key); } @Override public String getString(String key, String defaultValue) { return jO.optString(key, defaultValue); } @Override public byte[] getByteArr(String key) { throw new UnsupportedOperationException(); } @Override public byte[] getByteArr(String key, byte[] defaultValue) { throw new UnsupportedOperationException(); } @Override public JSONObject getJSONObject(String key) throws JSONException{ return jO.optJSONObject(key); } @Override public JSONArray getJSONArray(String key) throws JSONException { return jO.optJSONArray(key); } @Override public boolean containsKey(String key) { return jO.has(key); } @Override public void put(String key, BinarySerializable bS) { throw new UnsupportedOperationException(); } } private static class CursorRow implements Row{ private final Cursor cursor; public CursorRow(Cursor cursor){ this.cursor = cursor; } @Override public void put(String key, int value) { throw new UnsupportedOperationException(); } @Override public void put(String key, boolean value) { throw new UnsupportedOperationException(); } @Override public void put(String key, long value) { throw new UnsupportedOperationException(); } @Override public void put(String key, double value) { throw new UnsupportedOperationException(); } @Override public void put(String key, float value) { throw new UnsupportedOperationException(); } @Override public void put(String key, String value) { throw new UnsupportedOperationException(); } @Override public void put(String key, byte[] value) { throw new UnsupportedOperationException(); } @Override public void put(String key, JSONObject jO) { throw new UnsupportedOperationException(); } @Override public void put(String key, JSONArray jA) { throw new UnsupportedOperationException(); } @Override public void put(String key, JSONSerializable jS) throws JSONException { throw new UnsupportedOperationException(); } @Override public void put(String key, BinarySerializable bS) { throw new UnsupportedOperationException(); } @Override public int getInt(String key) { if(containsKey(key)) return cursor.getInt(cursor.getColumnIndex(key)); else return 0; } @Override public int getInt(String key, int defaultValue) { if(containsKey(key)) return getInt(key); else return defaultValue; } @Override public boolean getBool(String key) { if(containsKey(key)) return cursor.getInt(cursor.getColumnIndex(key)) == 1; else return false; } @Override public boolean getBool(String key, boolean defaultValue) { if(containsKey(key)) return getBool(key); else return defaultValue; } @Override public long getLong(String key) { if(containsKey(key)) return cursor.getLong(cursor.getColumnIndex(key)); else return 0; } @Override public long getLong(String key, long defaultValue) { if(containsKey(key)) return getLong(key); else return defaultValue; } @Override public double getDouble(String key) { if(containsKey(key)) return cursor.getDouble(cursor.getColumnIndex(key)); else return 0.0; } @Override public double getDouble(String key, double defaultValue) { if(containsKey(key)) return getDouble(key); else return defaultValue; } @Override public float getFloat(String key) { if(containsKey(key)) return cursor.getFloat(cursor.getColumnIndex(key)); else return (float) 0.0; } @Override public float getFloat(String key, float defaultValue) { if(containsKey(key)) return getFloat(key); else return defaultValue; } @Override public String getString(String key) { if(containsKey(key)) return cursor.getString(cursor.getColumnIndex(key)); else return null; } @Override public String getString(String key, String defaultValue) { if(containsKey(key)) return getString(key); else return defaultValue; } @Override public byte[] getByteArr(String key) { if(containsKey(key)) return cursor.getBlob(cursor.getColumnIndex(key)); else return null; } @Override public byte[] getByteArr(String key, byte[] defaultValue) { if(containsKey(key)) return getByteArr(key); else return defaultValue; } @Override public JSONObject getJSONObject(String key) throws JSONException { return new JSONObject(cursor.getString(cursor.getColumnIndex(key))); } @Override public JSONArray getJSONArray(String key) throws JSONException { return new JSONArray(cursor.getString(cursor.getColumnIndex(key))); } @Override public boolean containsKey(String key) { return cursor.getColumnIndex(key) >= 0; } } private static class ContentValuesRow implements Row{ private final ContentValues cV; public ContentValuesRow(ContentValues cV){ this.cV = cV; } @Override public void put(String key, int value) { cV.put(key, value); } @Override public void put(String key, boolean value) { cV.put(key, value); } @Override public void put(String key, long value) { cV.put(key, value); } @Override public void put(String key, double value) { cV.put(key, value); } @Override public void put(String key, float value) { cV.put(key, value); } @Override public void put(String key, String value) { cV.put(key, value); } @Override public void put(String key, byte[] value) { cV.put(key, value); } @Override public void put(String key, JSONObject jO) { cV.put(key, jO.toString()); } @Override public void put(String key, JSONArray jA) { cV.put(key, jA.toString()); } @Override public void put(String key, JSONSerializable jS) throws JSONException { cV.put(key, jS.toJSONObject().toString()); } @Override public void put(String key, BinarySerializable bS) { cV.put(key, bS.toBinary()); } @Override public int getInt(String key) { throw new UnsupportedOperationException(); } @Override public int getInt(String key, int defaultValue) { throw new UnsupportedOperationException(); } @Override public boolean getBool(String key) { throw new UnsupportedOperationException(); } @Override public boolean getBool(String key, boolean defaultValue) { throw new UnsupportedOperationException(); } @Override public long getLong(String key) { throw new UnsupportedOperationException(); } @Override public long getLong(String key, long defaultValue) { throw new UnsupportedOperationException(); } @Override public double getDouble(String key) { throw new UnsupportedOperationException(); } @Override public double getDouble(String key, double defaultValue) { throw new UnsupportedOperationException(); } @Override public float getFloat(String key) { throw new UnsupportedOperationException(); } @Override public float getFloat(String key, float defaultValue) { throw new UnsupportedOperationException(); } @Override public String getString(String key) { throw new UnsupportedOperationException(); } @Override public String getString(String key, String defaultValue) { throw new UnsupportedOperationException(); } @Override public byte[] getByteArr(String key) { throw new UnsupportedOperationException(); } @Override public byte[] getByteArr(String key, byte[] defaultValue) { throw new UnsupportedOperationException(); } @Override public JSONObject getJSONObject(String key) throws JSONException { throw new UnsupportedOperationException(); } @Override public JSONArray getJSONArray(String key) throws JSONException { throw new UnsupportedOperationException(); } @Override public boolean containsKey(String key) { throw new UnsupportedOperationException(); } } private static class ToStringRow implements Row{ public ToStringRow(String name, long rowid){ builder = new StringBuilder("Model name: ") .append(name) .append(ITEMSEP) .append(" ROWID: ") .append(rowid) .append(ITEMSEP) .append(" Values: "); } private static final String KVSEP = " => "; private static final String ITEMSEP = " , "; private final StringBuilder builder; @Override public void put(String key, int value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, boolean value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, long value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, double value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, float value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, String value) { builder.append(key) .append(KVSEP) .append(value) .append(ITEMSEP); } @Override public void put(String key, byte[] value) { builder.append(key) .append(KVSEP) .append("ByteArray") .append(ITEMSEP); } @Override public void put(String key, JSONObject jO) { builder.append(key) .append(KVSEP) .append("JSONObject") .append(ITEMSEP); } @Override public void put(String key, JSONArray jA) { builder.append(key) .append(KVSEP) .append("JSONArray") .append(ITEMSEP); } @Override public void put(String key, JSONSerializable jS) throws JSONException { builder.append(key) .append(KVSEP) .append("JSONSerializable") .append(ITEMSEP); } @Override public void put(String key, BinarySerializable bS) { builder.append(key) .append(KVSEP) .append("BinarySerializable") .append(ITEMSEP); } @Override public int getInt(String key) { throw new UnsupportedOperationException(); } @Override public int getInt(String key, int defaultValue) { throw new UnsupportedOperationException(); } @Override public boolean getBool(String key) { throw new UnsupportedOperationException(); } @Override public boolean getBool(String key, boolean defaultValue) { throw new UnsupportedOperationException(); } @Override public long getLong(String key) { throw new UnsupportedOperationException(); } @Override public long getLong(String key, long defaultValue) { throw new UnsupportedOperationException(); } @Override public double getDouble(String key) { throw new UnsupportedOperationException(); } @Override public double getDouble(String key, double defaultValue) { throw new UnsupportedOperationException(); } @Override public float getFloat(String key) { throw new UnsupportedOperationException(); } @Override public float getFloat(String key, float defaultValue) { throw new UnsupportedOperationException(); } @Override public String getString(String key) { throw new UnsupportedOperationException(); } @Override public String getString(String key, String defaultValue) { throw new UnsupportedOperationException(); } @Override public byte[] getByteArr(String key) { throw new UnsupportedOperationException(); } @Override public byte[] getByteArr(String key, byte[] defaultValue) { throw new UnsupportedOperationException(); } @Override public JSONObject getJSONObject(String key) throws JSONException { throw new UnsupportedOperationException(); } @Override public JSONArray getJSONArray(String key) throws JSONException { throw new UnsupportedOperationException(); } @Override public boolean containsKey(String key) { return false; } @Override public String toString(){ return builder.toString(); } } }