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.JSONArray; 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 = "Options") public class Option extends ReceiveModel { private static final String TAG = "Option"; @Column(name = "Question") private Question mQuestion; @Column(name = "Text") private String mText; // https://github.com/pardom/ActiveAndroid/issues/22 @Column(name = "RemoteId", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE) private Long mRemoteId; @Column(name = "NextQuestion") private String mNextQuestion; @Column(name = "NumberInQuestion") private int mNumberInQuestion; @Column(name = "InstrumentVersion") private int mInstrumentVersion; @Column(name = "Deleted") private boolean mDeleted; public Option() { super(); } /* * If the language of the instrument is the same as the language setting on the * device (or through the admin settings), then return the default option text. * * If another language is requested, iterate through option translations to * find translated text. * * If the language requested is not available as a translation, return the non-translated * text for the option. */ public String getText() { if (getQuestion().getInstrument().getLanguage().equals(getDeviceLanguage())) return mText; for(OptionTranslation translation : translations()) { if (translation.getLanguage().equals(getDeviceLanguage())) { return translation.getText(); } } // Fall back to default return mText; } public String getDeviceLanguage() { return Instrument.getDeviceLanguage(); } /* * Find an exisiting translation, or return a new OptionTranslation * if a translation does not yet exist. */ public OptionTranslation getTranslationByLanguage(String language) { for(OptionTranslation translation : translations()) { if (translation.getLanguage().equals(language)) { return translation; } } OptionTranslation translation = new OptionTranslation(); translation.setLanguage(language); return translation; } @Override public void createObjectFromJSON(JSONObject jsonObject) { try { Long remoteId = jsonObject.getLong("id"); // If an option already exists, update it from the remote Option option = Option.findByRemoteId(remoteId); if (option == null) { option = this; } if (AppUtil.DEBUG) Log.i(TAG, "Creating object from JSON Object: " + jsonObject); option.setText(jsonObject.getString("text")); option.setQuestion(Question.findByRemoteId(jsonObject.getLong("question_id"))); option.setRemoteId(remoteId); option.setNextQuestion(jsonObject.getString("next_question")); if (!jsonObject.isNull("number_in_question")) { option.setNumberInQuestion(jsonObject.getInt("number_in_question")); } option.setInstrumentVersion(jsonObject.getInt("instrument_version")); if (!jsonObject.isNull("deleted_at")) { option.setDeleted(true); } option.save(); // Generate translations JSONArray translationsArray = jsonObject.getJSONArray("translations"); for(int i = 0; i < translationsArray.length(); i++) { JSONObject translationJSON = translationsArray.getJSONObject(i); OptionTranslation translation = option.getTranslationByLanguage(translationJSON.getString("language")); translation.setOption(option); translation.setText(translationJSON.getString("text")); translation.save(); } } catch (JSONException je) { Log.e(TAG, "Error parsing object json", je); } } // Used for skip patterns public Question getNextQuestion() { return findByQuestionIdentifier(mNextQuestion); } public Question findByQuestionIdentifier(String question) { return Question.findByQuestionIdentifier(question); } private void setNextQuestion(String nextQuestion) { mNextQuestion = nextQuestion; } /* * Finders */ public static List<Option> getAll() { return new Select().from(Option.class).where("Deleted != ?", 1).orderBy("Id ASC").execute(); } public static Option findByRemoteId(Long id) { return new Select().from(Option.class).where("RemoteId = ?", id).executeSingle(); } /* * Relationships */ public List<OptionTranslation> translations() { return getMany(OptionTranslation.class, "Option"); } public List<Skip> skips() { return getMany(Skip.class, "Option"); } public List<Question> questionsToSkip() { return new Select("Questions.*").from(Question.class).innerJoin(Skip.class).on("Questions.Id = Skips.Question AND Skips.Option =?", getId()).execute(); } /* * Getters/Setters */ public Question getQuestion() { return mQuestion; } public void setQuestion(Question question) { mQuestion = question; } public void setText(String text) { mText = text; } public Long getRemoteId() { return mRemoteId; } public void setRemoteId(Long id) { mRemoteId = id; } public int getNumberInQuestion() { return mNumberInQuestion; } public int getInstrumentVersion() { return mInstrumentVersion; } private void setNumberInQuestion(int number) { mNumberInQuestion = number; } private void setInstrumentVersion(int version) { mInstrumentVersion = version; } private void setDeleted(boolean deleted) { mDeleted = deleted; } }