Skip to content

Instantly share code, notes, and snippets.

@heapwalker
Last active December 8, 2016 02:59
Show Gist options
  • Save heapwalker/2869236b7b12881b15854f939d92c994 to your computer and use it in GitHub Desktop.
Save heapwalker/2869236b7b12881b15854f939d92c994 to your computer and use it in GitHub Desktop.
To provide a java OO-styled class for reading / writing values to skygear `Record`. And make a Record `Parcelable`.
package com.example.sudoku;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import io.skygear.meta.RecordWrapper;
import io.skygear.skygear.Record;
/**
* It is to be defined by skygear user (this it is in our own package name).
* We had to create one class for each table in publicDB.
*
* Such class has implemented {@link Parcelable}. It can be directly included into / extracted from {@link android.os.Bundle}.
*/
public class PublicUser extends RecordWrapper {
public static final String TAG = "PublicUser";
/**
* The table name (in skygear's PublicDB)
*/
public static final String TABLE_NAME = "user";
/**
* Enumeration of certain columns in the table
*
* These constants are useful when:
* - getting / setting value to the source {@link Record} (as in below getter / setter function)
* - performing query on the table
*/
public static class Column {
/**
* A column pre-defined by skygear
*/
public static final String ID = "_id";
/**
* A column pre-defined by skygear
*/
public static final String USERNAME = "username";
/**
* A column pre-defined by skygear
*/
public static final String EMAIL = "email";
/**
* A custom column created for our own project
*/
public static final String FIRST_NAME = "first_name";
/**
* A custom column created for our own project
*/
public static final String LAST_NAME = "last_name";
}
/**
* For usage with a new {@link Record}
*/
public PublicUser() {
// such call is important
setRecord(new Record(TABLE_NAME));
}
public PublicUser(Parcel in) {
readFromParcel(in);
}
/**
* For usage with an existing {@link Record}
*/
public PublicUser(@NonNull Record record) {
setRecord(record);
}
/**
* Below we create a pair of convenient getter+setter for each **custom** field.
*
* Non-custom field (e.g. created_by, creator_at, etc) can be directly accessed via {@link #getRecord().getXXX()}.
*/
@Nullable
public String getUsername() {
return getTypedValue(Column.USERNAME, String.class);
}
public void setUsername(String username) {
getRecord().set(Column.USERNAME, username);
}
@Nullable
public String getEmail() {
return getTypedValue(Column.EMAIL, String.class);
}
public void setEmail(String email) {
getRecord().set(Column.EMAIL, email);
}
@Nullable
public String getFirstName() {
return getTypedValue(Column.FIRST_NAME, String.class);
}
public void setFirstName(@Nullable String firstName) {
getRecord().set(Column.FIRST_NAME, firstName);
}
@Nullable
public String getLastName() {
return getTypedValue(Column.LAST_NAME, String.class);
}
public void setLastName(@Nullable String lastName) {
getRecord().set(Column.LAST_NAME, lastName);
}
/**
* This field is required by Parcelable interface
* Every child class of {@link RecordWrapper} should define its own `Creator` field.
*/
public static final Creator<PublicUser> CREATOR = new Creator<PublicUser>() {
@Override
public PublicUser createFromParcel(Parcel in) {
return new PublicUser(in);
}
@Override
public PublicUser[] newArray(int size) {
return new PublicUser[size];
}
};
}
package io.skygear.meta;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import io.skygear.skygear.Record;
/**
* A wrapper class for {@link Record}.
* It also acts like a single parent class of all Record-enhanced-class.
*
* It is expected that the {@link #record} should be always set and NOT null.
*
* Such class has implemented {@link Parcelable}, so that the (child class) object can be directly included into / extracted from {@link android.os.Bundle}.
*/
public abstract class RecordWrapper implements Parcelable {
public static final String TAG = "RecordWrapper";
/**
* The source {@link Record} that this class wraps.
*/
private Record record;
/**
* Intentionally empty. And it should not be called directly in code.
*/
public RecordWrapper() {
}
public RecordWrapper(Parcel in) {
readFromParcel(in);
}
/**
* To let other component directly access the {@link Record}. Handy for accessing those public function of {@link Record}.
* @return
*/
@NonNull
public final Record getRecord() {
return record;
}
public final void setRecord(@NonNull Record record) {
this.record = record;
}
/**
* This function may be redundant, as it can be replaced by calling {@link #getRecord().getId()}.
* @return
*/
public final String getId() {
return record.getId();
}
/**
* To be called by child class only
* @param key
* @param defaultValue
* @param <T>
* @return
*/
@Nullable
protected final <T> T getTypedValue(@NonNull String key, @Nullable T defaultValue) {
Object value = record.get(key);
try {
return (T) value;
}
catch (ClassCastException e) {
Log.e(TAG, e.getMessage(), e);
}
catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return defaultValue;
}
/**
* To be called by child class only
* @param key
* @param type
* @param <T>
* @return
*/
@Nullable
protected final <T> T getTypedValue(@NonNull String key, Class<T> type) {
Object value = record.get(key);
try {
return (T) value;
}
catch (ClassCastException e) {
Log.e(TAG, e.getMessage(), e);
}
catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
return null;
}
protected void readFromParcel(Parcel in) {
try {
// reconstruct the Record from a json string
record = Record.fromJson(new JSONObject(in.readString()));
} catch (JSONException e) {
Log.e(TAG, e.getMessage(), e);
}
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// Simply write the whole (serialized) json string
dest.writeString(record.toJson().toString());
}
@Override
public int describeContents() {
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment