Android Open Source - Abstract-Model Model






From Project

Back to project page Abstract-Model.

License

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.

Java Source Code

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();
    }
    
  }
  
  
}




Java Source Code List

com.logician.abstractModel.AsyncModelFactory.java
com.logician.abstractModel.BinarySerializable.java
com.logician.abstractModel.Column.java
com.logician.abstractModel.JSONSerializable.java
com.logician.abstractModel.ModelListAdapter.java
com.logician.abstractModel.Model.java
com.logician.abstractModel.Util.java
com.logician.abstractModel.examples.MyDatabaseOpenHelper.java
com.logician.abstractModel.examples.User.java
com.logician.abstractModel.examples.UsersActivity.java