package org.adaptlab.chpir.android.survey.Models;
import java.util.List;
import org.adaptlab.chpir.android.activerecordcloudsync.ReceiveModel;
import org.adaptlab.chpir.android.survey.AppUtil;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
import com.activeandroid.query.Select;
@Table(name = "Rules")
public class Rule extends ReceiveModel {
private static final String TAG = "RuleModel";
@Column(name = "RuleType")
private RuleType mRuleType;
@Column(name = "Instrument")
private Instrument mInstrument;
@Column(name = "Params")
private String mParams;
@Column(name = "StoredValues")
private String mStoredValues;
@Column(name = "RemoteId", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
private Long mRemoteId;
public static enum RuleType {
INSTRUMENT_SURVEY_LIMIT_RULE, INSTRUMENT_TIMING_RULE, INSTRUMENT_SURVEY_LIMIT_PER_MINUTE_RULE,
INSTRUMENT_LAUNCH_RULE, PARTICIPANT_TYPE_RULE
};
// INSTRUMENT_SURVEY_RULE_LIMIT
public static final String MAX_SURVEYS_KEY = "max_surveys";
public static final String INSTRUMENT_SURVEY_COUNT_KEY = "instrument_survey_count";
// INSTRUMENT_TIMING_RULE
public static final String START_TIME_KEY = "start_time";
public static final String END_TIME_KEY = "end_time";
// INSTRUMENT_SURVEY_LIMIT_PER_MINUTE_RULE
public static final String NUM_SURVEYS_KEY = "num_surveys";
public static final String MINUTE_INTERVAL_KEY = "minute_interval";
public static final String SURVEY_TIMESTAMPS_KEY = "survey_timestamps";
public Rule() {
super();
mStoredValues = "";
}
public static Rule findByRuleTypeAndInstrument(RuleType ruleType, Instrument instrument) {
for (Rule rule : getAll()) {
if (rule.getRuleType() != null && rule.getRuleType().equals(ruleType) &&
rule.getInstrument() != null && rule.getInstrument().equals(instrument)) {
return rule;
}
}
return null;
}
public static List<Rule> getAll() {
return new Select().from(Rule.class).orderBy("Id ASC").execute();
}
public static Rule findByRemoteId(Long remoteId) {
return new Select().from(Rule.class).where("RemoteId = ?", remoteId).executeSingle();
}
@Override
public void createObjectFromJSON(JSONObject jsonObject) {
try {
Long remoteId = jsonObject.getLong("id");
// If a rule already exists, update it from the remote
Rule rule = Rule.findByRemoteId(remoteId);
if (rule == null) {
rule = this;
}
if (AppUtil.DEBUG) Log.i(TAG, "Creating object from JSON Object: " + jsonObject);
rule.setRuleType(jsonObject.getString("rule_type"));
rule.setInstrument(Instrument.findByRemoteId(jsonObject.getLong("instrument_id")));
rule.setParams(jsonObject.getString("rule_params"));
rule.setRemoteId(remoteId);
if (jsonObject.isNull("deleted_at")) {
rule.save();
} else {
Rule deletedRule = Rule.findByRemoteId(remoteId);
if (deletedRule != null) {
deletedRule.delete();
}
}
} catch (JSONException je) {
Log.e(TAG, "Error parsing object json", je);
}
}
public Long getRemoteId() {
return mRemoteId;
}
public JSONObject getParamJSON() {
try {
return new JSONObject(mParams);
} catch (JSONException je) {
Log.e(TAG, "Could not parse rule params: " + je);
return null;
}
}
public RuleType getRuleType() {
return mRuleType;
}
public Instrument getInstrument() {
return mInstrument;
}
public <T> void setStoredValue(String key, T value) {
try {
JSONObject jsonObject = mStoredValues.equals("") ? new JSONObject() : new JSONObject(mStoredValues);
if (AppUtil.DEBUG) Log.i(TAG, "Setting k: " + key + " to v: " + value);
jsonObject.put(key, value);
mStoredValues = jsonObject.toString();
} catch (JSONException je) {
if (AppUtil.DEBUG) Log.e(TAG, "Error setting json for stored value: (k: " + key +", v: " + value + ") :" + je);
}
}
public <T> T getStoredValue(String key) {
try {
JSONObject jsonObject = mStoredValues.equals("") ? new JSONObject() : new JSONObject(mStoredValues);
if (AppUtil.DEBUG) Log.i(TAG, "Getting value for k: " + key);
if (jsonObject.has(key)) {
return (T) jsonObject.get(key);
} else {
return null;
}
} catch (JSONException je) {
if (AppUtil.DEBUG) Log.e(TAG, "Error getting json value for stored value: (k: " + key +") :" + je);
return null;
}
}
/*
* Private
*/
private void setParams(String params) {
mParams = params;
}
private void setInstrument(Instrument instrument) {
mInstrument = instrument;
}
private void setRemoteId(Long id) {
mRemoteId = id;
}
private void setRuleType(String ruleType) {
if (validRuleType(ruleType)) {
mRuleType = RuleType.valueOf(ruleType);
} else {
// This should never happen
// We should prevent syncing data unless app is up to date
Log.wtf(TAG, "Received invalid rule type: " + ruleType);
}
}
private static boolean validRuleType(String ruleType) {
for (RuleType type : RuleType.values()) {
if (type.name().equals(ruleType)) {
return true;
}
}
return false;
}
}