package com.metaweb.gridworks.model; import java.io.Serializable; import java.io.Writer; import java.util.Calendar; import java.util.Date; import java.util.Properties; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonToken; import org.json.JSONException; import org.json.JSONWriter; import com.metaweb.gridworks.Jsonizable; import com.metaweb.gridworks.expr.EvalError; import com.metaweb.gridworks.expr.ExpressionUtils; import com.metaweb.gridworks.expr.HasFields; import com.metaweb.gridworks.util.ParsingUtilities; import com.metaweb.gridworks.util.Pool; public class Cell implements HasFields, Jsonizable { final public Serializable value; final public Recon recon; public Cell(Serializable value, Recon recon) { this.value = value; this.recon = recon; } public Object getField(String name, Properties bindings) { if ("value".equals(name)) { return value; } else if ("recon".equals(name)) { return recon; } return null; } public boolean fieldAlsoHasFields(String name) { return "recon".equals(name); } public void write(JSONWriter writer, Properties options) throws JSONException { writer.object(); if (ExpressionUtils.isError(value)) { writer.key("e"); writer.value(((EvalError) value).message); } else { writer.key("v"); if (value != null) { if (value instanceof Calendar) { writer.value(ParsingUtilities.dateToString(((Calendar) value).getTime())); writer.key("t"); writer.value("date"); } else if (value instanceof Date) { writer.value(ParsingUtilities.dateToString((Date) value)); writer.key("t"); writer.value("date"); } else { writer.value(value); } } else { writer.value(null); } } if (recon != null) { writer.key("r"); writer.value(Long.toString(recon.id)); Pool pool = (Pool) options.get("pool"); pool.pool(recon); } writer.endObject(); } public void save(Writer writer, Properties options) { JSONWriter jsonWriter = new JSONWriter(writer); try { write(jsonWriter, options); } catch (JSONException e) { e.printStackTrace(); } } static public Cell loadStreaming(String s, Pool pool) throws Exception { JsonFactory jsonFactory = new JsonFactory(); JsonParser jp = jsonFactory.createJsonParser(s); if (jp.nextToken() != JsonToken.START_OBJECT) { return null; } return loadStreaming(jp, pool); } static public Cell loadStreaming(JsonParser jp, Pool pool) throws Exception { JsonToken t = jp.getCurrentToken(); if (t == JsonToken.VALUE_NULL || t != JsonToken.START_OBJECT) { return null; } Serializable value = null; String type = null; Recon recon = null; while (jp.nextToken() != JsonToken.END_OBJECT) { String fieldName = jp.getCurrentName(); jp.nextToken(); if ("r".equals(fieldName)) { if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { String reconID = jp.getText(); recon = pool.getRecon(reconID); } else { // legacy recon = Recon.loadStreaming(jp, pool); } } else if ("e".equals(fieldName)) { value = new EvalError(jp.getText()); } else if ("v".equals(fieldName)) { JsonToken token = jp.getCurrentToken(); if (token == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (token == JsonToken.VALUE_NUMBER_INT) { value = jp.getLongValue(); } else if (token == JsonToken.VALUE_NUMBER_FLOAT) { value = jp.getDoubleValue(); } else if (token == JsonToken.VALUE_TRUE) { value = true; } else if (token == JsonToken.VALUE_FALSE) { value = false; } } else if ("t".equals(fieldName)) { type = jp.getText(); } } if (value != null) { if (type != null) { if ("date".equals(type)) { value = ParsingUtilities.stringToDate((String) value); } } return new Cell(value, recon); } else { return null; } } }