Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.io.StringWriter;
import org.kohsuke.stapler.export.Flavor;
import java.lang.reflect.Type;
import org.jvnet.tiger_types.Types;
import org.kohsuke.stapler.export.DataWriter;
import org.kohsuke.stapler.export.Model;
import org.kohsuke.stapler.export.ModelBuilder;

Expand All @@ -40,10 +41,103 @@ public class JenkinsExportedBeanSerializer extends JsonSerializer<Object> {

@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
StringWriter sw = new StringWriter();
var dw = Flavor.JSON.createDataWriter(value, sw);
// StringWriter sw = new StringWriter();
// var dw = Flavor.JSON.createDataWriter(value, sw);
Model p = MODEL_BUILDER.get(value.getClass());
p.writeTo(value, dw);
gen.writeRawValue(sw.toString());
p.writeTo(value, new JsonGeneratorDataWriter(gen));
}

private static class JsonGeneratorDataWriter implements DataWriter {
private final JsonGenerator gen;
Class classAttr;

public JsonGeneratorDataWriter(JsonGenerator gen) {
this.gen = gen;
classAttr = null;
}

@Override
public void name(String name) throws IOException {
gen.writeFieldName(name);
}

@Override
public void valuePrimitive(Object v) throws IOException {
if (v instanceof Integer) {
gen.writeNumber((Integer) v);
} else if (v instanceof Long) {
gen.writeNumber((Long) v);
} else if (v instanceof Float) {
gen.writeNumber((Float) v);
} else if (v instanceof Double) {
gen.writeNumber((Double) v);
} else if (v instanceof Boolean) {
gen.writeBoolean((Boolean) v);
} else if (v instanceof Byte) {
gen.writeNumber((Byte) v);
} else if (v instanceof Short) {
gen.writeNumber((Short) v);
} else if (v instanceof Character) {
gen.writeString(v.toString());
} else {
throw new IllegalArgumentException("Unsupported primitive type: " + v.getClass());
}
}

@Override
public void value(String v) throws IOException {
gen.writeString(v);
}

@Override
public void valueNull() throws IOException {
gen.writeNull();
}

@Override
public void startArray() throws IOException {
gen.writeStartArray();
}

@Override
public void endArray() throws IOException {
gen.writeEndArray();
}

@Override
public void type(Type expected, Class actual) throws IOException {
classAttr = map(expected, actual);
}

@Override
public void startObject() throws IOException {
gen.writeStartObject();
if (classAttr != null) {
name(CLASS_PROPERTY_NAME);
value(classAttr.getName());
classAttr = null;
}
}

@Override
public void endObject() throws IOException {
gen.writeEndObject();
}

Class map(Type expected, Class actual) {
if (actual == null) {
return null; // nothing to write
}
if (expected == actual) {
return null; // fast pass when we don't need it
}
if (expected == null) {
return actual; // we need to print it
}
if (Types.erasure(expected) == actual) {
return null; // slow pass
}
return actual;
}
}
}