package org.dynjs.debugger.agent.serializers;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.dynjs.debugger.Debugger;
import org.dynjs.runtime.*;
import java.io.IOException;
/**
* @author Bob McWhirter
*/
public class HandleSerializer extends JsonSerializer<Object> {
private Debugger debugger;
public HandleSerializer(Debugger debugger) {
super();
this.debugger = debugger;
}
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
serializeBody(value, jgen, provider);
jgen.writeEndObject();
}
public void serializeRef(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
int ref = this.debugger.getReferenceManager().getReference( value );
jgen.writeNumberField( "ref", ref );
if (value == Types.UNDEFINED) {
jgen.writeStringField("type", "undefined");
} else if (value == Types.NULL) {
jgen.writeStringField("type", "null");
} else if (value instanceof Boolean) {
jgen.writeStringField("type", "boolean");
jgen.writeBooleanField("value", (Boolean) value);
} else if (value instanceof Double) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Double) value);
} else if (value instanceof Long) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Long) value);
} else if (value instanceof String) {
jgen.writeStringField("type", "string");
jgen.writeStringField("value", (String) value);
} else if ( value instanceof JSFunction ) {
jgen.writeStringField("type", "function");
Object name = ((JSFunction) value).get( null, "name" );
if ( name != Types.UNDEFINED ) {
jgen.writeStringField( "name", name.toString() );
} else {
jgen.writeStringField( "name", "" );
}
jgen.writeStringField( "inferredName", "" );
SourceProvider source = ((JSFunction) value).getSource();
if ( source != null ) {
jgen.writeNumberField( "scriptId", source.getId() );
}
} else if (value instanceof JSObject) {
jgen.writeStringField("type", "object");
} else if ( value instanceof SourceProvider ) {
jgen.writeStringField("type", "script");
}
jgen.writeEndObject();
}
public void serializeAsMapEntry(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
int ref = this.debugger.getReferenceManager().getReference(value);
jgen.writeFieldName("" + ref);
serialize(value, jgen, provider);
}
public void serializeBody(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
int ref = this.debugger.getReferenceManager().getReference(value);
jgen.writeNumberField("handle", ref);
if (value == Types.UNDEFINED) {
jgen.writeStringField("type", "undefined");
} else if (value == Types.NULL) {
jgen.writeStringField("type", "null");
} else if (value instanceof Boolean) {
jgen.writeStringField("type", "boolean");
jgen.writeBooleanField("value", (Boolean) value);
} else if (value instanceof Double) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Double) value);
} else if (value instanceof Long) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Long) value);
} else if (value instanceof String) {
jgen.writeStringField("type", "string");
jgen.writeStringField("value", (String) value);
} else if (value instanceof JSObject) {
jgen.writeStringField("type", "object");
serializeJSObject((JSObject) value, jgen, provider);
} else if (value instanceof SourceProvider) {
serializeScript((SourceProvider) value, false, jgen, provider);
}
}
public void serializeScript(SourceProvider value, boolean includeSource, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStringField("type", "script");
jgen.writeStringField("name", value.getName());
jgen.writeNumberField("id", value.getId());
if (includeSource) {
jgen.writeStringField("source", value.getSource());
}
jgen.writeNumberField("sourceLength", value.getSourceLength());
jgen.writeNumberField("lineCount", value.getLineCount());
jgen.writeNumberField("scriptType", 2);
jgen.writeNumberField("compilationType", 0);
}
private void serializeJSObject(JSObject result, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeFieldName("properties");
jgen.writeStartArray();
NameEnumerator enumerator = result.getAllEnumerablePropertyNames();
while (enumerator.hasNext()) {
String name = enumerator.next();
Object propResult = result.getProperty(null, name);
if (propResult == Types.UNDEFINED) {
jgen.writeStartObject();
jgen.writeStringField("name", name);
jgen.writeNumberField("ref", this.debugger.getReferenceManager().getReference(Types.UNDEFINED));
jgen.writeEndObject();
} else {
PropertyDescriptor prop = (PropertyDescriptor) propResult;
if (prop.hasValue()) {
Object value = prop.getValue();
jgen.writeStartObject();
jgen.writeStringField("name", name);
jgen.writeNumberField("ref", this.debugger.getReferenceManager().getReference(prop.getValue()));
if (value == Types.UNDEFINED) {
jgen.writeStringField("type", "undefined");
} else if (value == Types.NULL) {
jgen.writeStringField("type", "null");
} else if (value instanceof Boolean) {
jgen.writeStringField("type", "boolean");
jgen.writeBooleanField("value", (Boolean) value);
} else if (value instanceof Double) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Double) value);
} else if (value instanceof Long) {
jgen.writeStringField("type", "number");
jgen.writeNumberField("value", (Long) value);
} else if (value instanceof String) {
jgen.writeStringField("type", "string");
jgen.writeStringField("value", (String) value);
}
jgen.writeEndObject();
} else {
// WHAT?
}
}
}
jgen.writeEndArray();
}
}