/**
*
*/
package org.commcare.android.database.user.models;
import org.commcare.android.database.EncryptedModel;
import org.commcare.android.models.AndroidSessionWrapper;
import org.commcare.android.storage.framework.MetaField;
import org.commcare.android.storage.framework.Persisted;
import org.commcare.android.storage.framework.Persisting;
import org.commcare.android.storage.framework.Table;
import org.commcare.util.CommCareSession;
import org.commcare.util.SessionFrame;
import org.javarosa.core.util.MD5;
/**
* A Session State Descriptor contains all of the information that can be persisted
* about a CommCare session. It is immutable and reflects a specific state.
*
* @author ctsims
*
*/
@Table("android_cc_session")
public class SessionStateDescriptor extends Persisted implements EncryptedModel {
public static final String META_DESCRIPTOR_HASH = "descriptorhash";
public static final String META_FORM_RECORD_ID = "form_record_id";
@Persisting(1)
@MetaField(value=META_FORM_RECORD_ID, unique=true)
private int formRecordId = -1;
@Persisting(2)
private String sessionDescriptor = null;
@MetaField(value=META_DESCRIPTOR_HASH)
public String getHash() {
return MD5.toHex(MD5.hash(sessionDescriptor.getBytes()));
}
//Wrapper for serialization (STILL SKETCHY)
public SessionStateDescriptor() {
}
public SessionStateDescriptor(AndroidSessionWrapper state) {
this.formRecordId = state.getFormRecordId();
sessionDescriptor = this.createSessionDescriptor(state.getSession());
}
public boolean isEncrypted(String data) {
// TODO Auto-generated method stub
return false;
}
public boolean isBlobEncrypted() {
// TODO Auto-generated method stub
return false;
}
public int getFormRecordId() {
return formRecordId;
}
public SessionStateDescriptor reMapFormRecordId(int idForNewRecord) {
SessionStateDescriptor copy = new SessionStateDescriptor();
copy.formRecordId = idForNewRecord;
copy.sessionDescriptor = sessionDescriptor;
return copy;
}
public void fromBundle(String serializedDescriptor) {
this.sessionDescriptor = serializedDescriptor;
}
public String getSessionDescriptor() {
return this.sessionDescriptor;
}
/**
* Serializes the session into a string which is unique for a
* given path through the application, and which can be deserialzied
* back into a live session.
*
* TODO: Currently we rely on this state being semantically unique,
* but it may change in the future. Rely on the specific format as
* little as possible.
*
* @param session
* @return
*/
private String createSessionDescriptor(CommCareSession session) {
//TODO: Serialize into something more useful. I dunno. JSON/XML/Something
String descriptor = "";
for(String[] step : session.getFrame().getSteps()) {
descriptor += step[0] + " ";
if(step[0] == SessionFrame.STATE_COMMAND_ID) {
descriptor += step[1] + " ";
} else if(step[0] == SessionFrame.STATE_DATUM_VAL || step[0] == SessionFrame.STATE_DATUM_COMPUTED) {
descriptor += step[1] + " " + step[2] + " ";
}
}
return descriptor.trim();
}
public void loadSession(CommCareSession session) {
String[] tokenStream = sessionDescriptor.split(" ");
int current = 0;
while(current < tokenStream.length) {
String action = tokenStream[current];
if(action.equals(SessionFrame.STATE_COMMAND_ID)) {
session.setCommand(tokenStream[++current]);
} else if(action.equals(SessionFrame.STATE_DATUM_VAL) || action.equals(SessionFrame.STATE_DATUM_COMPUTED)) {
session.setDatum(tokenStream[++current], tokenStream[++current]);
}
current++;
}
}
}